In my C Makefile I have the following lines:
ifeq ($(VERBOSE_PRINT), TRUE)
CFLAGS += -D TRUE
else
CFLAGS += -D FALSE
endif
As you can tell by it's name, this flag indicated whether I should print debug statements or not.
In other place at my C code, I'm defining TRUE and FALSE with
#define FALSE 0
#define TRUE !FALSE
Then when I'm trying to compile my code, I get the following error:
types.h:6:0: error: "FALSE" redefined [-Werror]
#define FALSE 0
<command-line>:0:0: note: this is the location of the previous definition
If I delete the definition of TRUE and FALSE from my C code, my program get's crazy.
What's going on and how can I solve this conflict?
Thanks ahead.
You can't use the same name for two different incompatible things, so you'll need to change one of them. Most likely you want to change your Makefile, since what you have makes no sense. Something like:
ifeq ($(VERBOSE_PRINT), TRUE)
CFLAGS += -DDEBUG=1
else
CFLAGS += -DDEBUG=0
endif
Then in your C code you can have
#if DEBUG
printf( ... debugging messages ... )
#endif
On the compiler command line, -DXYZ is equivalent to -DXYZ=1 (POSIX c99). This means that with -DFALSE on the command line, you've got both #define FALSE 1 and #define FALSE 0, which is a non-benign redefinition. Benign redefinition of a macro is OK (meaning that the sequence of replacement tokens is the same in both the current and new definition — see C11 §6.10.3 Macro replacement ¶1-2).
You need to use a different variable in your code to decide whether to do printing:
#ifdef VERBOSE_PRINT
printf("Debugging!\n");
#endif
You can then use -DVERBOSE_PRINT on the command line to enable printing and leave it out to disable it. Alternatively, you can use:
#if VERBOSE_PRINT
printf("Debugging!\n");
#endif
Then your makefile can contain:
ifeq ($(VERBOSE_PRINT), TRUE)
CFLAGS += -DVERBOSE_PRINT=TRUE
else
CFLAGS += -DVERBOSE_PRINT=FALSE
endif
This technique is less common. It will work as if you have #define VERBOSE_PRINT 0 if you don't specify a value on the compiler command line (C11 §6.10.1 Conditional inclusion ¶4).
Related
I am trying to understand the following macro from the following URL:
do { \
word _v(l) = vec_len (V); \
V = _vec_resize ((V), 1, (_v(l) + 1) * sizeof ((V)[0]), (H), (A)); \
(V)[_v(l)] = (E); \
} while (0)
what is the significance of _v(l)? Is it just a variable or something more?
The _v macro is defined in vec.h at line 207:
#define _v(var) _vec_##var
This prepends _vec_ before var. You can observe this by asking your favorite compiler to print the output of the preprocessor stage (-E flag for clang/gcc and /E for msvc).
#define _v(var) _vec_##var
word _v(l) = vec_len (V);
Is expanded into:
word _vec_l = vec_len (V);
It is a variable whose name is generated. The name probably includes the current line number to make it unique. Therefore using this macro twice in a line may or may not work.
To see what the macro expands to, run gcc -E to only preprocess the code but not compile it. Do a bit of research about this -E computer option, it is helpful in many similar cases as well.
In my C code, I need to check my kernel version and act according to it.
In the makefile I have the following:
KERNEL_MAJOR :=$(word 1, $(subst ., ,$(KERNEL_HEADERS)))
KERNEL_MINOR :=$(word 2, $(subst ., ,$(KERNEL_HEADERS)))
KERNEL_MICRO :=$(word 1, $(subst -, ,$(word 3, $(subst ., ,$(KERNEL_HEADERS)))))
KERNEL_PATCH_LEVEL :=$(word 1, $(subst ., ,$(word 2, $(subst -, ,$(KERNEL_HEADERS)))))
KARGS := KCPPFLAGS="-DKERNEL_MAJOR=$(KERNEL_MAJOR) -DKERNEL_MINOR=$(KERNEL_MINOR) -DKERNEL_MICRO=$(KERNEL_MICRO) -DKERNEL_PATCH_LEVEL=$(KERNEL_PATCH_LEVEL)"
Samples:
3.0.101-0.47.71-default looks like:
KCPPFLAGS="-DKERNEL_MAJOR=3 -DKERNEL_MINOR=0 -DKERNEL_MICRO=101 -DKERNEL_PATCH_LEVEL=0"
4.1.21.x86_64.1 (notice KERNEL_PATCH_LEVEL):
KCPPFLAGS="-DKERNEL_MAJOR=4 -DKERNEL_MINOR=1 -DKERNEL_MICRO=21 -DKERNEL_PATCH_LEVEL="
I have macro in my code to check if kernel is 3.0.101.0 or 3.0.76.0:
#if defined(KERNEL_MAJOR) && defined(KERNEL_MINOR) && defined(KERNEL_MICRO) && defined(KERNEL_PATCH_LEVEL) && \
(KERNEL_VERSION(KERNEL_MAJOR,KERNEL_MINOR,KERNEL_MICRO) == KERNEL_VERSION(3,0,101) || KERNEL_VERSION(KERNEL_MAJOR,KERNEL_MINOR,KERNEL_MICRO) == KERNEL_VERSION(3,0,76)) \
&& (KERNEL_PATCH_LEVEL == 0)
There are 3 && boolean expressions, if expression #1 is ok, then i want to continue to expression #2, if expression #2 continue, i will continue to expression #3.
When i try to compile (make..) on kernel version 4.1.21.x86_64.1 i receive:
error: operator '==' has no left operand
This is because -DKERNEL_PATCH_LEVEL=" - see the output.
I would expect the make to prevent me from getting to that && condition since expression #2 has failed (3.0.101 or 3.0.76)
If you read: https://gcc.gnu.org/onlinedocs/gcc-3.0.2/cpp_4.html, you will find:
The `#if' directive allows you to test the value of an arithmetic expression, rather than the mere existence of one macro. Its syntax is
#if expression ...
expression is a C expression of integer type, subject to stringent restrictions. It may contain:
...
Macros. All macros in the expression are expanded before actual computation of the expression's value begins.
Identifiers that are not macros, which are all considered to be the number zero. ...
So if you had:
#if defined(FOO) && FOO == 1
And then didn't define foo, it would resolve the expression to:
0 && 0 == 1
which would then resolve to #if 0, which is valid. However, if you defined FOO to be blank, then it would resolve to:
1 && == 1
The precompiler would then try to parse the expression, and get a syntax error, and fail. Despite several comments that seem to be out on the web, the precompiler does not short-circuit the parsing of the expression, just the evaluation of the expression.
If you wanted to get around this, you can use some macro trickery as follows:
#define COMBINE1(W,Y,Z) W##Y##Z
#define COMBINE(W,Y,Z) COMBINE1(W,Y,Z)
#define ISEMPTY(val) COMBINE(val,4,val) == 4
#if defined FOO
#if ISEMPTY(FOO)
#pragma message "FOO DEFINED AS EMPTY"
#else
#pragma message "FOO DEFINED (NOT EMPTY)"
#endif
#else
#pragma message "FOO NOT DEFINED"
#endif
which gives:
~/sandbox/tst6> gcc tst2.c
tst2.c:12: note: #pragma message: FOO NOT DEFINED
~/sandbox/tst6> gcc tst2.c -DFOO=
tst2.c:7: note: #pragma message: FOO DEFINED AS EMPTY
~/sandbox/tst6> gcc tst2.c -DFOO=1
tst2.c:9: note: #pragma message: FOO DEFINED (NOT EMPTY)
You are right in believing that the C preprocessor, like the C compiler,
performs short-circuit evaluation of &&- and ||-expressions.
But you are wrong in believing the preprocessor, unlike the compiler,
can perform "short-circuit" evaluation of nonsensical token sequences,
provided that the nonsense is in one of the contexts:
TRUE || [nonsense]
or
FALSE && [nonsense]
Just like the compiler, any sequence the preprocessor can evaluate as an
expression, short-circuiting or not, must be a (well-formed) expression,
which
FALSE && ( == 0)
is not.
All the #if conditions pass because KERNEL_PATCH_LEVEL is defined. It's just defined as an empty string. -DKERNEL_PATCH_LEVEL= is equivalent to
#define KERNEL_PATCH_LEVEL
Which, of course, will pass an #if (defined) test.
It's somewhat difficult to test if a macro is empty. It might be easier to modify your makefile to define KERNEL_PATCH_LEVEL as some special value (like 0 or -1) if it isn't present in the version string.
My question today should not be very much complicated, but I simply can't find a reason/solution. As a small, reproducible example, consider the following toy C code
#define _state_ 0
#if _state_ == 1
int foo(void) {return 1;}
#else
/* check GCC flags first
note that -mfma will automatically turn on -mavx, as shown by [gcc -mfma -dM -E - < /dev/null | egrep "SSE|AVX|FMA"]
so it is sufficient to check for -mfma only */
#ifndef __FMA__
#error "Please turn on GCC flag: -mfma"
#endif
#include <immintrin.h> /* All OK, compile C code */
void foo (double *A, double *B) {
__m256d A1_vec = _mm256_load_pd(A);
__m256d B_vec = _mm256_broadcast_sd(B);
__m256d C1_vec = A1_vec * B_vec;
}
#endif
I am going to compile this test.c file by
gcc -fpic -O2 -c test.c
Note I did not turn on GCC flag -mfma, so the #error will be triggered. What I would expect, is that compilation will stop immediately after GCC sees this #error, but this is what I got with GCC 5.3:
test.c:14:2: error: #error "Please turn on GCC flag: -mfma"
#error "Please turn on GCC flag: -mfma"
^
test.c: In function ‘foo’:
test.c:22:11: warning: AVX vector return without AVX enabled changes the ABI [-Wpsabi]
__m256d A1_vec = _mm256_load_pd(A);
^
GCC does stops, but why does it also pick up a line after #error? Any explanation? Thanks.
For people who want to try, there are some hardware requirement. You need an x86-64 with AVX and FMA instruction sets.
I have a draft copy of the C ISO spec, and in §4/4 - it states
The implementation shall not successfully translate a preprocessing translation unit containing a #error preprocessing directive unless it is part of a group skipped by conditional inclusion.
Later on, in §6.10.5, where #error is formally defined, it says
A preprocessing directive of the form
# error pp-tokens opt new-line
causes the implementation to produce a diagnostic message that includes the specified
sequence of preprocessing tokens.
In other words, the spec only requires that any code that has an #error just needs to fail to compile and report an error message along the way, not that the compilation immediately needs to terminate as soon as #error is reached.
Given that it's considered good practice to always check the top-level errors reported by a compiler before later ones, I'd imagine a competent programmer who saw a string of errors beginning with an #error directive would likely know what was going on.
For example, does MIN_N_THINGIES below compile to 2? Or will I recompute the division every time I use the macro in code (e.g. recomputing the end condition of a for loop each iteration).
#define MAX_N_THINGIES (10)
#define MIN_N_THINGIES ((MAX_N_THINGIES) / 5)
uint8_t i;
for (i = 0; i < MIN_N_THINGIES; i++) {
printf("hi");
}
This question stems from the fact that I'm still learning about the build process. Thanks!
If you pass -E to gcc it will show what the preprocessor stage outputted.
gcc -E test.c | tail -n11
Outputs:
# 3 "test.c" 2
int main() {
uint8_t i;
for (i = 0; i < ((10) / 5); i++) {
printf("hi");
}
return 0;
}
Then if you pass -s flag to gcc you will see that the division was optimized out. If you also pass the -o flag you can set the output files and diff them to see that they generated the same code.
gcc -S test.c -o test-with-div.s
edit test.c to make MIN_N_THINGIES equal a const 2
gcc -S test.c -o test-constant.s
diff test-with-div.s test-constant.s
// for educational purposes you should look at the .s files generated.
Then as mentioned in another comment you can change the optimization flag by using -O...
gcc -S test.c -O2 -o test-unroll-loop.s
Will unroll the for loop even such that there isn't even a loop.
Preprocessor will replace MIN_N_THINGIES with ((10)/5), then it is up to the compiler to optimize ( or not ) the expression.
Maybe. The standard does not mandate that it is or it is not. On most compilers it will do after passing optimization flags (for example gcc with -O0 does not do it while with -O2 it even unrolls the loop).
Modern compilers perform even much more complicated techniques (vectorization, loop skewing, blocking ...). However unless you really care about performance, for ex. you program HPC, program real time system etc., you probably should not care about the output of the compiler - unless you're just interested (and yes - compilers can be a fascinating subject).
No. The preprocessor does not calculate macros, they're handled by the compiler. The preprocessor can calculate arithmetic expressions (no floating point values) in #if conditionals though.
Macros are simply text substitutions.
Note that the expanded macros can still be calculated and optimized by the compiler, it's just that it's not done by the preprocessor.
The standard mandates that some expressions are evaluated at compile time. But note that the preprocessor does just text splicing (well, almost) when the macro is called, so if you do:
#define A(x) ((x) / (S))
#define S 5
A(10) /* Gives ((10) / (5)) == 2 */
#undef S
#define S 2
A(20) /* Gives ((20) / (2)) == 10 */
The parenteses are to avoid idiocies like:
#define square(x) x * x
square(a + b) /* Gets you a + b * a + b, not the expected square */
After preprocessing, the result is passed to the compiler proper, which does (most of) the computation in the source that the standard requests. Most compilers will do a lot of constant folding, i.e., computing (sub)expressions made of known constants, as this is simple to do.
To see the expansions, it is useful to write a *.c file of a few lines, just with the macros to check, and run it just through the preprocessor (typically someting like cc -E file.c) and check the output.
see in one code i have written
void my_function()
{
INT32 i; /* Variable for iteration */
/* If system is little-endian, store bytes in array as reverse order */
#ifdef LITTLE
{
// i m using i for operating one loop
}
#endif
/* If the system is big-endian, store bytes in array as forward order */
#ifdef BIG
{
// using i for loop
}
#endif
return;
}
by compiling this code with -Wall flag it shows
warning: unused variable ‘i’
why?
how can i remove this?
Put the declaration of i just inside the {} where you actually use it. Even better if you have C99, declare the loop variable inside the for(int i = 0, i < bound; ++i)
By defining either LITTLE or BIG. I doubt many compilers give that warning for this code when one of those symbols are defined. If you still have the warning, then you might change the second #ifdef to an #else.
I don't see any #endif anywhere -- presumably in the real code, those appear.
You need to define either BIG or LITTLE (as mentioned elsewhere).
In order to stop this happening again in the future, you can raise a specific compile-time error using the following:
#if !defined LITTLE && !defined BIG
#error You haven't defined one of your macro names
#endif
Alternatively, you could include i only when using either code block by surrounding it with #if defined as well:
#if defined LITTLE || defined BIG
INT32 i;
#endif
In both cases, note the keyword to use is #if not #ifdef or #ifndef.
You do not have to declare the iteration number. Just do it in your for statement.
for(int i = 0; i < 6; i++){
// insert loop code here
}
hey i got the answer...
see BIG & LITTLE are preposser flag & they are given at compile time.
when i was compiling my project with make file i was giving this flag at compile time but while testing each individual file i was compiling like
gcc -Wall -c filename.c
This was comming because i havent given any flag so compiler going to neglet that much portion of code & i was getting warning.
gcc -Wall -c -LITTLE filename.c
works perfectly...