C, how can a macro register a unittest for execution? - c

How can libraries such as GTest use a single macro G_TEST(...) to both define the function and register it as a test function? I'm looking for a way to do the same for my C99 project.
Example
#include <stdio.h>
#include "my_test_header_that_doesnt_exist.h"
TEST_MACRO(mytest)
{
printf("Hello, world\n");
return 0;
}
TEST_MACRO(mytest2)
{
printf("Hello, world 2\n");
return 2;
}
int main(int argc, char** argv)
{
RUN_TESTS();
return 0;
}
Can't figure out how to register the tests so they are known from RUN_TESTS()

By passing an -E option to g++ you can inspect the code after preprocessing. Example code using the GTest library:
#include <gtest/gtest.h>
TEST(testcase, mytest) {
// Code
}
int main() {
return RUN_ALL_TESTS();
}
And compiling it with:
g++ -E -Igtest_include_path example.cpp -oexample_preprocessed.cpp
The TEST macro expanded to:
class testcase_mytest_Test : public ::testing::Test {
public:
testcase_mytest_Test() {}
private:
virtual void TestBody();
static ::testing::TestInfo* const test_info_ __attribute__ ((unused));
testcase_mytest_Test(testcase_mytest_Test const &);
void operator=(testcase_mytest_Test const &);
};
::testing::TestInfo* const testcase_mytest_Test ::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "testcase", "mytest", __null, __null, ::testing::internal::CodeLocation("cpp_test.c", 3), (::testing::internal::GetTestTypeId()), ::testing::Test::SetUpTestCase, ::testing::Test::TearDownTestCase, new ::testing::internal::TestFactoryImpl< testcase_mytest_Test>);
void testcase_mytest_Test::TestBody() {
// Code
}
And RUN_ALL_TESTS() is not a macro:
inline int RUN_ALL_TESTS() {
return ::testing::UnitTest::GetInstance()->Run();
}
So it's in fact a complicated chain of preprocessor macros that make up a class out of your test case, and does all sorts of things to link it to the machinery that runs it.
Obviously you are not going to be able to do it like this in a C99 project, as GTest is a C++ library, and it heavily relies on C++ features to do the job.
If you wish to understand how it works fully, you should check out the GTest code in its repository: https://github.com/google/googletest

Related

How to fix my error while compiling my C file? [duplicate]

I'm working on a simple class List, but when compiling the header and cpp file, I get the error: undefined reference to `main'
What am I doing wrong, and how could I fix this?
Here is the list.h file that has simple headers:
list.h
#ifndef LIST_H
#define LIST_H
#include <string>
const int DEFAULT_CAPACITY = 100;
class List
{
public:
List();
List(int capacity);
~List();
void push_back(std::string s);
int size() const;
std::string at(int index) const;
private:
std::string* mData;
int mSize;
int mCapacity;
};
#endif
And here is the list.cpp file:
list.cpp
#include "list.h"
#include <string>
List::List(){
mData = new std::string[DEFAULT_CAPACITY];
mSize = 0;
mCapacity = 100;
};
List::List(int capacity){
mData = new std::string[capacity];
mSize = 0;
mCapacity = capacity;
};
List::~List(){
delete[] mData;
};
void List::push_back(std::string s){
if (mSize<mCapacity){
mData[mSize] = s;
mSize++;
}
};
int List::size() const{
return mSize;
};
std::string List::at(int index) const{
return mData[index];
};
I tried experimenting around with "using namespace std" and how to include , but I can't figure out how to get these errors to go away. What is causing them?
You should be able to compile list.cpp, you can't link it unless you have a main program. (That might be a slight oversimplification.)
The way to compile a source file without linking it depends on what compiler you're using. If you're using g++, the command would be:
g++ -c list.cpp
That will generate an object file containing the machine code for your class. Depending on your compiler and OS, it might be called list.o or list.obj.
If you instead try:
g++ list.cpp
it will assume that you've defined a main function and try to generate an executable, resulting in the error you've seen (because you haven't defined a main function).
At some point, of course, you'll need a program that uses your class. To do that, you'll need another .cpp source file that has a #include "list.h" and a main() function. You can compile that source file and link the resulting object together with the object generated from list.cpp to generate a working executable. With g++, you can do that in one step, for example:
g++ list.cpp main.cpp -o main
You have to have a main function somewhere. It doesn't necessarily have to be in list.cpp. And as a matter of style and code organization, it probably shouldn't be in list.cpp; you might want to be able to use that class from more than one main program.
Undefined reference to main() means that your program lacks a main() function, which is mandatory for all C++ programs. Add this somewhere:
int main()
{
return 0;
}

How to use macro for calling function?

I want to call function according to func_name string.
My code is here below:
#define MAKE_FUNCNAME func_name##hello
void call_func(void* (*func)(void))
{
func();
}
void *print_hello(void)
{
printf("print_hello called\n");
}
int main(void)
{
char func_name[30] = "print_";
call_func(MAKE_FUNCNAME);
return 0;
}
But this code doesn't work. I want code to work like call_func(print_hello). But preprocessor treated my code like call_func("print_hello"). How to use macro in C to make my exception? Or is it not possible using C?
Then problem with your code is that the value of func_name is only known at run-time.
You can however to it like this:
#define MAKE_FUNCNAME(FUNCNAME) FUNCNAME##hello
void call_func(void* (*func)(void))
{
func();
}
void *print_hello(void)
{
printf("print_hello called\n");
}
int main(void)
{
call_func(MAKE_FUNCNAME(print_));
return 0;
}
But it is not possible to use a string value within macro parameters like in your code snippet.
If you want to get call functions with their names using string values you can use a table to store function pointer with function names like this:
struct {
const char *name;
void (*ptr)(void);
};
You can use an array of this structure to find out the function pointer at run-time using a string value. This is the most common solution to using run-time strings to call functions using their names.
You can't do that. The value of func_name is known at run-time (even though it is a const char *), while you want to determine what to call at precompile-time. You should turn your cpp macro into something different (such as an if/switch statement or using an indirection).
Maybe you could have a look to dlsym().
Not sure I really understand the question, but if you want to "build" the function name at runtime and then call the corresponding function, it should be possible with dlsym()
/* compile with: gcc example.c -ldl -rdynamic */
#include <dlfcn.h>
#include <stdio.h>
int print_hello(void)
{
return printf("hello\n");
}
int main(int argc, char *argv[])
{
const char *name = "print_hello";
if (argc == 42)
print_hello(); /* for compiler not to remove print_hello at
* compile time optimisation in this example*/
void *handle = dlopen(NULL /* self */, RTLD_NOW);
int (*f)(void) = dlsym(handle, name);
f();
return dlclose(handle);
}

Structured module interface for C

I want to improve my C code style a bit and as well encapsulate my code a bit more. Furthermore, the interface to my modules should be clear and easy to handle.
In my project I have several modules containing the different functions.
modul_1.c
static int modul_1_func_2(void);
void modul_1_func_1(void) { ... }
int modul_1_func_2(void) { ... }
void modul_1_func_3(int) { ... }
modul_1.h
void modul_1_func_1(void);
void modul_1_func_3(int);
There are local and global module-function.
With a struct, it should be possible to call the functions from the main like
modul_1.modul_1_func_1();
In know that I have to use function pointers within the structure, but I don't know how to initialize them.
I don't want a a dynamic pointer where I have to change the address each time before I use it. I want to have several pointers within the structure — one for each global function.
I already tried this without success:
typedef void (*func_1_temp)(void);
typedef void (*func_3_temp)(int);
struct {
func_1_temp func_1;
func_3_temp func_3;
} HMI = {
func_1 = &modul_1_func_1(),
func_3 = &modul_1_func_3()
};
Does anyone know what I have to do that my dreams come true?
I hope to get a clear interface with this approach.
For other ideas I am thankful as well.
The name of a function is, at least in this context, directly usable as a
pointer to the function.
mod.h
void modul_1_func_1(void);
void modul_1_func_3(int);
granicus% cat mod.c
static int modul_1_func_2(void);
mod.c
void modul_1_func_1(void) { return; }
int modul_1_func_2(void) { return 1; }
void modul_1_func_3(int x) { modul_1_func_2(); return; }
granicus% cat main.c
#include "mod.h"
typedef void (*func_1_temp)(void);
typedef void (*func_3_temp)(int);
main.c
int main(void) {
struct {
func_1_temp func_1;
func_3_temp func_3;
} HMI = {
modul_1_func_1,
modul_1_func_3,
};
HMI.func_1();
return 0;
}
Compiling on my system with gcc -Wall main.c mod.c gives no errors or warnings.

How should I organize this C project

I am doing this programming assignment in C. But I am confused as to how to organize it.
So, here is the situation. I have two tree implementations and declare their struct/includes/function prototypes and so on in two separate header files. Then I have two c source code for the two implementations. Now here comes the problem. I have one test c file (only one main function for running tests) for the ADTs of Trees. Since the two implementations are going to use the same test. How can I avoid making two copies of the same main.c file? when I include the header file of tree implementation1, I can do gcc Tree_implementation1.c main.c. But to do implementation2, I have to got back in the main source file and manually change the include to tree implementation2, and then I can use the same compilation command. How do I work around this to toggle between the two implementations with only one main.c?
Use the preprocessor and a constant that you can set on the command line:
In your main.c:
#ifdef TREE_IMPL1
#include "TreeImplementation1.h"
#else
#include "TreeImplementation2.h"
#endif
// ...
int main(int argc, char **argv)
{
#ifdef TREE_IMPL1
// code for testing TreeImplementation1
#else
// code for testing TreeImplementation2
#endif
}
When you compile, pass or omit TREE_IMPL1 on the command line, or set it in your IDE:
gcc -DTREE_IMPL1 main.c ...
Do your implementations have the same name? They shouldn't.
If (or when) they don't have the same name, you can just include both headers in main.c and test either one depending on some preprocessor directive.
//main.c
#include "Tree_implementation1.h"
#include "Tree_implementation2.h"
int main()
{
#ifdef TEST_FIRST
testFirstTree(); //declared in Tree_implementation1.h
#else
testSecondTree(); //declared in Tree_implementation2.h
#endif
return 0;
}
Another solution for your problem is using of dynamic interface.
Work the way like that:
#include "Imp_1.h"
#include "Imp_2.h"
typedef void (*TreeFunctionType1)(Tree,param);
typedef void (*TreeFunctionType2)(Tree);
typedef struct ITree
{
TreeFunctionType1 func1;
TreeFunctionType2 func2;
}ITree;
static ITree _Itree={0};
void SetImp(TreeFunctionType1 f1,TreeFunctionType2 f2)
{
tree.func1 = f1;
tree.func2 = f2;
}
/*Use only this functions in your Tests code*/
//{
void Func1(Tree tree,Param param)
{
(*_Itree.func1)(tree,param);
}
void Func2(Tree tree)
{
(*_Itree.func2)(tree);
}
//}
int main(int argc, char const *argv[])
{
SetImp(Imp_1_f1,Imp_1_f2);
TestCode();
SetImp(Imp_2_f1,Imp_2_f2);
TestCode();
return 0;
}

Can I re-define a function or check if it exists?

I have a question about (re-)defining functions. My goal is to have a script where I can choose to define a function or not.
Like this:
void func(){}
int main(){
if (func)func();
}
AND without the function, just:
int main(){
if (func)func();
}
Anybody an idea?
You can do this in GCC using its weak function attribute extension:
void func() __attribute__((weak)); // weak declaration must always be present
int main() {
if (func) func();
// ...
}
// optional definition:
void func() { ... }
This works even if func() is defined in another .c file or a library.
Something like this, I think. Haven't used function pointers much, so I may have gotten the syntax slightly wrong.
void func()
{
#define FUNC_PRESENT
// code
}
void (*funcptr)();
#ifdef FUNC_PRESENT
funcptr = func;
#else
funcptr = NULL;
#endif
int main()
{
if (funcptr)
funcptr();
}
Use function pointers, set them dynamically based on runtime conditions, and check for null pointers or wrap them in methods that do that check for you.
Only option in C I can think of.
In C++ you could combine templates and DLLs to dynamically define at runtime.
Really the only way that you can "choose to define a function or not" is with C preprocessor directives. For example:
#ifdef some_name
void func() {
do_whatever();
}
#else
//the else part is optional
#endif
To set these "variables" you use #define some_name
The trouble is, all of this needs to be done at compile time (before that, actually) so it can't be done with an if statement like in your example. If you want an if statement to control your program flow, just use it and don't bother with trying to rename functions or using function pointers or something.
Introduction
I guess that you are trying to do this:
Two modules, a.o and b.o
b.o contains a definition for void foo()
a.o calls void foo() only if b.o is also linked into the final executable.
This could be useful for a "plugin" system.
Variation 1
You can simulate it using function pointers. I don't know enough C to write this in proper C code, but pseudocode looks like this:
a.h
extern collectionOfFuncPtrs_t list;
int addFuncPtr();
a.c
#include "a.h"
collectionOfFuncPtrs_t list;
int addFuncPtr(FuncPtr p) {
- add func ptr to list
- return 0
}
int main() {
- loop through list of function pointers
- call functions through them
}
b.c
#include "a.h"
void bar() { /* ... */ }
static int dummy = addFuncPtr(&bar);
c.c
#include "a.h"
void ayb() { /* ... */ }
static int dummy = addFuncPtr(&ayb);
Conclusion
Now, you can link in b.o and/or c.o as you wish, and int main() will only call bar() and/or ayb() if they exist.
Variation 2
Experiment with variations on this theme if it looks like it may be useful to you. In particular, if you have only a specific number of conditionally-defined functions, you could use a bunch of individual function pointers rather than some list:
a.h
extern fptr_t bar_ptr, ayb_ptr;
a.c
#include "a.h"
int main() {
if (bar_ptr)
bar_ptr();
if (ayb_ptr)
ayb_ptr();
}
b.c
#include "a.h"
void bar() { /* ... */ }
fptr_t bar_ptr = &bar;
b_dummy.c
#include "a.h"
fptr_t bar_ptr = 0;
c.c
#include "a.h"
void ayb() { /* ... */ }
fptr_t ayb_ptr = &ayb;
c_dummy.c
#include "a.h"
fptr_t ayb_ptr = 0;
Conclusion
Now either link b.o or b_dummy.o; and either link c.o or c_dummy.o.
I hope you get the general idea, anyway...!
Bootnote
This is a lot easier in C++ where you can write a module registration system very easily with std::maps and constructors.
In C? Only by using the preprocessor as stated in other answers.
C isn't a dynamic language like, say, Python.
The right way to do what I think you're asking about in C is to use function pointers. You can take the address of a function, assign it to a variable, test it for nil, etc. However, plain old C isn't a very dynamic language; you might be better off using a different language.
if you don't mind compiler specific extension, you can use __if_exists:
#include <iostream>
using namespace std;
// uncomment the following, and it'll still work
void maybeFunc(){ cout << "running maybe" << endl; }
int main(){
cout << "hi!" << endl;
__if_exists(maybeFunc)
cout << "maybe exists!" << endl;
maybeFunc();
}
}
this works in msvc by default, and in clang if you use the -fms-extensions flag.

Resources