I have two source files: one I want to test via asserts, the second containing the asserts.
My problem is that I do not want the testing to be run each time the program itself is run, so is there a way to toggle assert testing on or off depending on a makefile argument?
Or will I have to create another source file, containing both the code I want to test and the assert testing itself?
man 3 assert says
If the macro NDEBUG is defined at the moment <assert.h> was last
included, the macro assert() generates no code, and hence does
nothing at all.
gcc ... -DNDEBUG is intended for a release build, and will not do anything in assert().
My problem is that I do not want the testing to be run each time the
program itself is run
If only the second file you mention contains the assert statements, why would the test code be run when you run the program?
Here is a typical way to divide the code for a module Foo containing a function Bar and its unit test:
Foo.h
#ifndef FOO_H
#define FOO_H
int Foo_Bar(int i);
#endif
Foo.c
#include "Foo.h"
int Foo_Bar(int i)
{
/*to be implemented*/
return -1;
}
FooTest.c
#include "Foo.h"
#include <assert.h>
int main(void)
{
assert(Foo_Bar(0) == 0);
return 0;
}
myprog.c
#include "Foo.h"
int main(void)
{
int bar = Foo_Bar(0);
/*...*/
return 0;
}
Related
I have a master.c and slave.c file. Both are compiled seperately, producing different contiki-ng modules.
As they both use a similar function, I created a helpers.h and helpers.c file, and added #include "helpers.h" to main.c and slave.c to deduplicate this function.
Additionally, I need to use the LOG_INFO function from log.h for logging in both slave.c/master.c and in helpers.c. log.h requires the macro LOG_MODULE to be set to the name of the Module (Master or Slave).
master.c:
#define LOG_MODULE "Master"
#include "sys/log.h"
#include "helpers.h"
void main() {
do_something();
}
slave.c:
#define LOG_MODULE "Slave"
#include "sys/log.h"
#include "helpers.h"
void main() {
do_something();
}
helpers.h:
void do_something();
helpers.c:
#include "sys/log.h"
#include "helpers.h"
void do_something() {
...
LOG_INFO("Result: x");
...
}
My problem is the following:
Even though I include "helpers.h" AFTER defining LOG_MODULE in master.c/slave.c, I still get a complaint about LOG_MODULE not being defined when I use LOG_INFO in helpers.c.
What is a proper and elegant solution to define LOG_MODULE with their respective values in slave.c and master.c, and have that definition used by helpers.c?
The helpers.c is a separate compile unit and during the compilation of it, it only "sees" the #define's in the headers included only in that file.
To achieve what you what you want, you would need to:
Move the definition of all the functions that use logging from .c to .h file.
Make the logging functions inline in this header to prevent linking problems if master.c and slave.c are then linked together to create a single binary.
helpers.h
#include "sys/log.h"
inline void do_something() {
...
LOG_INFO("Result: x");
...
}
We have a repo that contains library functions for example (gcc is used to compile and link).
//print.h
#ifndef __PRINT_H_
#define __PRINT_H_
#define MAX_ARRAY 10
void print_hex(int cal[]);
#endif
// print.c
#include <stdio.h>
void print_hex(int val[]) {
for (int I=0;I<MAX_ARRAY;I++) {
printf("%i\n",val[I]);
}
}
The above is compiled into a libprint.a.1.0.0. My app is then compiled using this library
//main.c
#include "print.h"
int main(int argc, int arg[]) {
int vals[MAX_ARRAY];
memset(vals,8,MAX_ARRAY*sizeof(int));
print_hex(vals);
return 0;
}
And everything is fine and works (assuming have typed the above out correctly). But then someone decides to make a change in the library where someone Makes the following change.
//print.h
...
#define MAX_ARRAY 50
...
The library is recompiled to libprint.a.1.1.0
This new static library is now used when compiling and linking our main.c. However, the new print.h was not copied to the include directory so the main.c is using an old print.h where MAX_ARRAY is smaller.
Now in this case we might get any behaviour as the print function runs off the end of the passed in array. As a user of the library there is no way to necessarily know that the header file is wrong until I compile and run the application, or perhaps even hours of running when the program starts to go crazy.
What is the standard way to avoid this issue?
Is there a way to add a version to a header file to ensure the correct library is linked?
I realise I could do this by creating a new function in print.c called get_version(), and use that in main.c to check against some defines in print.h to ensure veracity but I was wondering if there was a way without the user application having to specifically check library and header versions at run time.
Yes. And don't do it.
The libfuse library uses a macro FUSE_USE_VERSION that should be defined by the client to differentiate between different versions. Internally it works similar to feature_test_macros.
So in your library it would look like:
print.h:
#ifndef __PRINT_H_
#define __PRINT_H_
#if PRINT_USE_VERSION == 1
#define MAX_ARRAY 10
void print_hex_version_1(int cal[]);
static inline
void print_hex(int cal[]) {
print_hex_version_1(val);
}
#elif PRINT_USE_VERSION == 2
#define MAX_ARRAY 50
void print_hex_version_2(int cal[]);
static inline
void print_hex(int cal[]) {
print_hex_version_2(val);
}
#else
#error unknown PRINT_USE_VERSION
#endif
#endif
print_version_1.c:
#define PRINT_USE_VERSION 1
#include <stdio.h>
void print_hex_version_1(int val[]) {
for (int I=0;I<MAX_ARRAY;I++) {
printf(“%i\n”,val[I]);
}
}
print_version_2.c:
#define PRINT_USE_VERSION 2
#include <stdio.h>
void print_hex_version_2(int val[]) {
for (int I=0;I<MAX_ARRAY;I++) {
printf(“%i\n”,val[I]);
}
}
Or similar, hope you'll you get the idea. Using this method you can distribute all possible versions of your library at once. And clients can link against multiple versions of your library. Which ends up being spaghetti code, unstable, unreliable, unfixable and unmaintainable.
On a global scale, it makes no sense. Just create a api that isn't dependent on a macro definition and take the array size as an argument. Check if the size of the array is equal to some predefined value and notify your client with error code that he did something wrong.
I'm working on a small open source project in C where I'm trying to use a test framework with C (the framework is min_unit).
I have a foo.h file with prototypes, and foo.c, with the implementation.
In my test file, tests.c, I have
#include "../test_framework/min_unit.h"
#include "foo.c"
... test cases ...
the problem is, because I have a main() function in foo.c (which I need to compile it), I can't compile tests.c because I get an error that states
note: previous definition of ‘main’ was here
int main() {
My question is, is there a way to make it so that the main() function in foo.c is conditional, so that it does not compile when I'm running tests.c? It's just annoying to have to remove and add main over and over.
The easiest way to use conditional compilation is to use #ifdef statements. E.g., in foo.c you have:
#ifdef NOT_TESTING //if a macro NOT_TESTING was defined
int main() {
//main function here
}
#endif
While in test.c, you put:
#ifndef NOT_TESTING //if NOT_TESTING was NOT defined
int main() {
//main function here
}
#endif
When you want to compile the main function in foo.c, you simply add the option -DNOT_TESTING to your compile command. If you want to compile the main function in test.c, don't add that option.
Haven't you try the use of pre-processor compiler conditions? May be you've tried but it doesn't work, hum?
Anyway, you probably should:
1- Define a token at top of "tests.c" class file like:
#defined foo_MIN_UNIT_TEST
2- Surround your "main() { ... } " method in "foo.c" class file with #ifndef / #endif like:
#ifndef foo_MIN_UNIT_TEST //consider using #ifndef not #ifdef!!!
int main()
{ ... }
#endif
3- This way, when you compile your unit test files, the main() method of foo.c will not be included in compile time and the only main() method of tests will be available to compiler.
For further reading: http://www.cprogramming.com/
Regards.
I have second level include that is giving me grief:
Undefined first referenced
symbol in file
function2 /var/tmp//ccAPaWbT.o
ld: fatal: symbol referencing errors. No output written to run
collect2: ld returned 1 exit status
Main file:
#include "functions02.c"
int main(){
int x = funcion2();
}
functions02.c file:
#ifndef FUNCTIONS02_C
#define FUNCTIONS02_C
int funcion2();
#if __INCLUDE_LEVEL__ == 0
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include "functions01.c"
int main() {
return function2();
}
#endif
int function2()
return function1();
}
#endif
functions01.c file:
#ifndef FUNCTIONS01_C
#define FUNCTIONS01_C
int funcion1();
#if __INCLUDE_LEVEL__ == 0
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
int main() {
return function1();
}
#endif
int function1()
return 10;
}
#endif
I am assuming that this can be fixed manipulated using __INCLUDE_LEVEL__ or manipulating linking on gcc compiling but I can't find forking variant.
First of all is it possible to achieve what I am looking for without putting functions in external header files?
Second what would be the correct way of doing it?
EDIT:
I realized that I had forgotten to add function dependencies to them. That is the includes which are used by functions can not be excluded by adding them just next to main function warped in exclusion if close.
Yes, it is possible to include / exclude any part of the code using compile time flags (and in the code using #if's) as you are trying to do.
In your case, I assume you have not defined __INCLUDE_LEVEL__ flag, hence the linker is not able to find funciton2, so the error.
If you define it, you will have three "main()" :-), it will fail again. So, you need to rework your code a bit.
Also, #include'ing a "C" file is not advisable and not used in practice. I assume you are just trying to experiment & learn, which is fine.
I'm trying to understand how global variables and functions work in C. My program compiles and works fine with gcc, but does not compile with g++. I have the following files:
globals.h:
int i;
void fun();
globals.c:
#include "stdlib.h"
#include "stdio.h"
void fun()
{
printf("global function\n");
}
main.c:
#include "stdlib.h"
#include "stdio.h"
#include "globals.h"
void myfun();
int main()
{
i=1;
myfun();
return 0;
}
And finally, myfun.c:
#include "stdlib.h"
#include "stdio.h"
#include "globals.h"
void myfun()
{
fun();
}
I get the following error when compiling with g++:
/tmp/ccoZxBg9.o:(.bss+0x0): multiple definition of `i'
/tmp/ccz8cPTA.o:(.bss+0x0): first defined here
collect2: ld returned 1 exit status
Any ideas why? I would prefer to compile with g++.
Every file you include globals.h from will define "int i".
Instead, put "extern int i;" into the header file and then put the actual definition of "int i = 1;" in globals.c.
Putting header guards around globals.h would be sensible too.
Edit: In answer to your question its because a #include works kind of like a cut and paste. It pastes the contents of the included file into the c file that you are calling include from. As you include "globals.h" from main.c and myfun.c you define int i = 1 in both files. This value, being global, gets put into the table of linkable values. If you have the same variable name twice then the linker won't be able to tell which one it needs and you get the error you are seeing. Instead by adding extern on the front in the header file you are telling each file that "int i" is defined somewhere else. Obviously, you need to define it somewhere else (and ONLY in one place) so defining it in globals.c makes perfect sense.
Hope that helps :)
I would add an include guard in your globals file
#ifndef GLOBALS_H
#define GLOBALS_H
int i;
void fun();
#endif
Edit: Change your globals to be like this (using extern as the other answer describes)
globals.h
extern int i;
extern void fun();
globals.c
#include "stdlib.h"
#include "stdio.h"
int i;
void fun()
{
printf("global function\n");
}
I compiled it with
g++ globals.c main.c myfun.c
and it ran ok
Several things wrong here; several other things highly recommended:
globals.h:
#ifndef GLOBALS_H
#define GLOBALS_H
extern int my_global;
#ifdef __cplusplus
extern "C" {
#endif
void fun();
#ifdef __cplusplus
}
#endif
#endif
/* GLOBALS_H */
globals.c:
#include <stdlib.h>
#include <stdio.h>
#include "globals.h"
int my_global;
void fun()
{
printf("global function: %d\n", my_global);
}
main.c:
#include <stdlib.h>
#include <stdio.h>
#include "globals.h"
void myfun();
int main()
{
my_global=1;
myfun();
return 0;
}
void myfun()
{
fun();
}
You should declare "extern int myvar" in your header, and actually allocate "int myvar" in one and only one .c file.
You should include "globals.h" in every file that uses "myvar" - including the file where it's allocated.
Especially if you're planning on mixing C and C++ modules, you should use 'extern "C"' to distinguish non-C++ functions.
System headers should be "#include <some_header.h>"; your own headers should use quotes (#include "myheader.h") instead.
Short variable names like "i" might be OK for a strictly local variable (like a loop index), but you should always use longer, descriptive names whenever you can't avoid using a global variable.
I added a "printf" for my_global.
'Hope that helps!
I had this problem when porting some old C code to C++. The problem was it was a project that was connected to a database, and i wanted to port the database to c++ but not the rest. The database pulled in some C dependencies that couldn't be ported, so i needed the C code that overlapped both the database and the other project to compile in g++ as well as gcc...
The solution to this problem is to define all variables as extern in the .h file. then when you compile in either gcc or g++ it will report symbols missing in the .c files. So edit the .c files in the error messages and insert the declaration into all the .c files that need the variables. Note: you may have to declare it in multiple .c files, which is what threw me and why I was stuck on this problem for ages.
Anyway this solved my problem and the code compiles cleanly under both gcc and g++ now.