I wanted to #define some macros based on whether particular directory is present in Linux, I can't use any fopen/directory/stat API's here since they are exposed during compilation phase
Example,
Need to set
---->Someway to check directory existing using C macro, i.e before compilation phase
#define RANDOM 100
#else
#define RANDOM 200
Need help here.
You can define a macro from the command line using the -D preprocessor option, in your case:
gcc -o demo demo.c -DRANDOM=$(test -d /path/to/some/dir && echo 100 || echo 200)
You simply read RANDOM from your program:
#include <stdio.h>
int main(void)
{
printf("%d\n", RANDOM);
}
You can't do this as the preprocessor textually replaces one value with another (more precisely it replaces tokens). It is done before the actual C code compilation.
You need to have variable RANDOM (not macro definition) and assign it with the value runtime.
int RANDOM = 0;
if(directory_exists(directory))
{
RANDOM = 200
}
else
{
RANDOM = 500
}
and use it later in your code.
Related
So I'm having a tough time with a school project. The goal is to make a self-replicating code, name Sully.c. That program must output it's own source code (it's a quine) into a program named Sully_x.c, where x is an integer in the source code, then compile said program and execute it iff x > 0. x must decrement from one copy to the next, but not from the original Sully.c to Sully_5.c.
Here is my code so far:
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int k = 5;
#define F1 int main(void){int fd = open("Sully_5.c", 0);if(fd != -1){close(fd);k-=1;}char buff[62];(sprintf)(buff, "Sully_%d.c", k);FILE *f = fopen(buff, "w");fprintf(f, "#include <fcntl.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <unistd.h>\nint k = %d;\n#define F1 %s\n#define F2(x) #x\n#define F3(x) F2(x)\nconst char *s = F3(F1);\nF1\n", k, s);fclose(f);(sprintf)(buff, "gcc -Wall -Wextra -Werror Sully_%d.c -o Sully_%d", k, k);system(buff);if (k != 0){(sprintf)(buff, "./Sully_%d", k);system(buff);}return 0;}
#define F2(x) #x
#define F3(x) F2(x)
const char *s = F3(F1);
F1
That code works, and checks all the requirements for the program. However, I'm using a method that checks something other than the code itself -> I'm checking if sully_5.c already exists or not. If it doesn't, x doesn't move, if it does, then it is decremented.
Another method would have been to use argv[0] or the macro __FILE__, but both these options are explicitly forbidden for the assignment and considered cheating.
But, apparently there are other methods that doesn't require any of the above technique. I can't think of any, because if Sully.c and Sully_5.c need different behaviors but the same source code, than there must be an external variable that needs to influence the code behavior, or so is my hypothesis.
Am I right? Wrong? How else could this be done?
... there must be an external variable that needs to influence the code behavior
How else could this be done?
You can define or not some preprocessing variables (e.g. -Daze or -Daze=12 etc) to generate a different code using conditional compilation without changing the source
The execution can also use the argument(s) given to the program when it is run to change its behavior
I am using go-hdf5 to read an hdf5 file into golang. I am on windows7 using a pretty recent copy of mingw and hdf5 1.8.14_x86 and it seems like trying to use any of the predefined types doesn't work, let's focus for example on T_NATIVE_UINT64. I have reduced the issue to the following, which basically leaves go-hdf5 out of the problem and points at something quite fundamental going wrong:
package main
/*
#cgo CFLAGS: -IC:/HDF_Group/HDF5/1.8.14_x86/include
#cgo LDFLAGS: -LC:/HDF_Group/HDF5/1.8.14_x86/bin -lhdf5 -lhdf5_hl
#include "hdf5.h"
#include <stdio.h>
void print_the_value2() { printf("the value of the constant is %d\n", H5T_NATIVE_UINT64); }
*/
import "C"
func main() {
C.print_the_value2()
}
You obviously need to have hdf5 and point the compiler at the headers/dlls and running go get, then executing prints this on my pc
the value of the constant is -1962924545
Running variations of the above, in how/where the constant is read, will give different answers for the value of H5T_NATIVE_UINT64. However I am pretty sure that is none are the right value and in fact trying to use a type with the id returned doesn't work, unsurprisingly.
If I write and run a "real" C program, I get different results
#include <stdio.h>
#include "hdf5.h"
hid_t _go_hdf5_H5T_NATIVE_UINT64() { return H5T_NATIVE_UINT64; }
int main()
{
printf("the value of the constant is %d", _go_hdf5_H5T_NATIVE_UINT64());
}
Compiling using
C:\Temp>gcc -IC:/HDF_Group/HDF5/1.8.14_x86/include -LC:/HDF_Group/HDF5/1.8.14_x86/bin -lhdf5 -lhdf5_hl -o stuff.exe stuff.c
and running gives me
the value of the constant is 50331683
And that appears to be the right value as I can use it directly from my go program. Obviously I want to be able to use the constants instead. Any idea why this could be happening?
Extra info following comments below:
I looked for the definition of H5T_NATIVE_UINT64 in the hdf5 headers and see the following
c:\HDF_Group\HDF5\1.8.14_x86\include>grep H5T_NATIVE_UINT64 *
H5Tpkg.h:H5_DLLVAR size_t H5T_NATIVE_UINT64_ALIGN_g;
H5Tpublic.h:#define H5T_NATIVE_UINT64 (H5OPEN H5T_NATIVE_UINT64_g)
H5Tpublic.h:H5_DLLVAR hid_t H5T_NATIVE_UINT64_g;
The whole header is here
http://www.hdfgroup.org/ftp/HDF5/prev-releases/hdf5-1.8.14/src/unpacked/src/H5Tpublic.h
Thanks!
H5T_NATIVE_UINT64 is NOT a constant but a #define that ultimately evaluates to (H5Open(), H5T_NATIVE_UINT64_g), which cgo does not understand.
It's easy to check by turning on debug output on gcc's preprocessor:
gcc -E -dM your_test_c_file.c | grep H5T_NATIVE_UINT64
Result:
#define H5T_NATIVE_UINT64 (H5OPEN H5T_NATIVE_UINT64_g)
Now the same for H5OPEN:
gcc -E -dM test_go.c | grep '#define H5OPEN'
gives:
#define H5OPEN H5open(),
Right now, cgo does understand simple integer constant defines like #define VALUE 1234, or anything that the gcc preprocessor will turn into an integer constant. See the function func (p *Package) guessKinds(f *File) in $GOROOT/src/cmd/cgo/gcc.go.
I'm attempting to refactor a piece of legacy code and I'd like a snapshot of all of the macros defined at a certain point in the source. The code imports a ridiculous number of headers etc. and it's a bit tedious to track them down by hand.
Something like
#define FOO 1
int myFunc(...) {
PRINT_ALL_DEFINED_THINGS(stderr)
/* ... */
}
Expected somewhere in the output
MACRO: "FOO" value 1
I'm using gcc but have access to other compilers if they are easier to accomplish this task.
EDIT:
The linked question does not give me the correct output for this:
#include <stdio.h>
#define FOO 1
int main(void) {
printf("%d\n", FOO);
}
#define FOO 0
This very clearly prints 1 when run, but gcc test.c -E -dM | grep FOO gives me 0
To dump all defines you can run:
gcc -dM -E file.c
Check GCC dump preprocessor defines
All defines that it will dump will be the value defined (or last redefined), you won't be able to dump the define value in all those portions of code.
You can also append the option "-Wunused-macro" to warn when macros have been redefined.
This question already has answers here:
Difference between preprocessor directive #if and normal if
(3 answers)
Closed 9 years ago.
I learned that if or #if can both be used for condition checks.
As we can check conditions using if, why would we use preprocessor #if?
What difference will it make to my code if I use #if instead of if?
Which one is better to use and why?
if and #if are different things with different purposes.
If you use the if statement, the condition is evaluated at runtime, and the code for both branches exists within the compiled program. The condition can be based on runtime information, such as the state of a variable. if is for standard flow control in a program.
If you use the preprocessor's #if, the condition is evaluated at compile-time (originally this was before compile-time, but these days the preprocessor is usually part of the compiler), and the code for the false branch is not included in the compiled program. The condition can only be based on compile-time information (such as #define constants and the like). #if is for having different code for different compile-time environments (for instance, different code for compiling on Windows vs. *nix, that sort of thing).
we could not say which better to use, because one is used in the compilation phase (#if) and the other one is used in the runtime phase(if)
#if 1
printf("this code will be built\n");
#else
printf("this code will not\n");
#endif
try to build the above code with gcc -E and you will see that your compiler will generate another code containing only :
printf("this code will be build\n");
the other printf will not be present in the new code (pre processor code) and then no present in the program binary.
Conclusion: the #if is treated in the compilation phase but the normal if is treated when your program run
You can use the #if 0 in a part of your code inorder to avoid the compiler to compile it. it's like you have commented this part
example
int main(void) {
printf("this code will be build\n");
#if 0
printf("this code will not\n");
#endif
}
it's equivalent to
int main(void) {
printf("this code will be built\n");
/*
printf("this code will not\n");
*/
}
Hey both are different
#if Tests if the condition is true at the compile time.
if is evaluated at runtime.
You should use #if when the outcome of the condition is known at compile time and regular if when outcome is not known until runtime.
#if DEBUG
I know at compile time I am making a debug build
if (date == DateTime.Today)
Depends on what day it is
Some uses of #if are:
You want to put extra prints, or checks when you build a debug version of your code
you want to ensure the compiler doesn't include a .h file twice
you want to write code that will use different system calls, and depending on the system it gets compiled on use the appropriate ones.
Because all of the above are checked at compile time this means that:
The condition must be able to be evaluated at compiletime
The produced code will not contain the branches that evaluate to false, leading to smaller code, and faster, as the condition is not checked every time the program is run.
Examples:
Adding extra checks only for debug mode:
#define DEBUGLEVEL 2
#if DEBUGLEVEL > 1
printf("The value of x is: %d", x);
#end if
#if DEBUGLEVEL > 2
printf("The address of x is: %x", &x);
ASSERT(x > 100);
#end if
Ensuring header only gets included once:
#ifndef PERSON_H
#define PERSON_H
class Person{
....
};
#end if
Having different code depending on platform:
#ifdef WINDOWS
time = QueryPerformanceCounter(..);
#else
time = gettimeofday(..);
#endif
I have code that has a lot of complicated #define error codes that are not easy to decode since they are nested through several levels.
Is there any elegant way I can get a list of #defines with their final numerical values (or whatever else they may be)?
As an example:
<header1.h>
#define CREATE_ERROR_CODE(class, sc, code) ((class << 16) & (sc << 8) & code)
#define EMI_MAX 16
<header2.h>
#define MI_1 EMI_MAX
<header3.h>
#define MODULE_ERROR_CLASS MI_1
#define MODULE_ERROR_SUBCLASS 1
#define ERROR_FOO CREATE_ERROR_CODE(MODULE_ERROR_CLASS, MODULE_ERROR_SUBCLASS, 1)
I would have a large number of similar #defines matching ERROR_[\w_]+ that I'd like to enumerate so that I always have a current list of error codes that the program can output. I need the numerical value because that's all the program will print out (and no, it's not an option to print out a string instead).
Suggestions for gcc or any other compiler would be helpful.
GCC's -dM preprocessor option might get you what you want.
I think the solution is a combo of #nmichaels and #aschepler's answers.
Use gcc's -dM option to get a list of the macros.
Use perl or awk or whatever to create 2 files from this list:
1) Macros.h, containing just the #defines.
2) Codes.c, which contains
#include "Macros.h"
ERROR_FOO = "ERROR_FOO"
ERROR_BAR = "ERROR_BAR"
(i.e: extract each #define ERROR_x into a line with the macro and a string.
now run gcc -E Codes.c. That should create a file with all the macros expanded. The output should look something like
1 = "ERROR_FOO"
2 = "ERROR_BAR"
I don't have gcc handy, so haven't tested this...
The program 'coan' looks like the tool you are after. It has the 'defs' sub-command, which is described as:
defs [OPTION...] [file...] [directory...]
Select #define and #undef directives from the input files in accordance with the options and report them on the standard output in accordance with the options.
See the cited URL for more information about the options. Obtain the code here.
If you have a complete list of the macros you want to see, and all are numeric, you can compile and run a short program just for this purpose:
#include <header3.h>
#include <stdio.h>
#define SHOW(x) printf(#x " = %lld\n", (long long int) x)
int main(void) {
SHOW(ERROR_FOO);
/*...*/
return 0;
}
As #nmichaels mentioned, gcc's -d flags may help get that list of macros to show.
Here's a little creative solution:
Write a program to match all of your identifiers with a regular expression (like \#define :b+(?<NAME>[0-9_A-Za-z]+):b+(?<VALUE>[^(].+)$ in .NET), then have it create another C file with just the names matched:
void main() {
/*my_define_1*/ my_define_1;
/*my_define_2*/ my_define_2;
//...
}
Then pre-process your file using the /C /P option (for VC++), and you should get all of those replaced with the values. Then use another regex to swap things around, and put the comments before the values in #define format -- now you have the list of #define's!
(You can do something similar with GCC.)
Is there any elegant way I can get a list of #defines with their final numerical values
For various levels of elegance, sort of.
#!/bin/bash
file="mount.c";
for macro in $(grep -Po '(?<=#define)\s+(\S+)' "$file"); do
echo -en "$macro: ";
echo -en '#include "'"$file"'"\n'"$macro\n" | \
cpp -E -P -x c ${CPPFLAGS} - | tail -n1;
done;
Not foolproof (#define \ \n macro(x) ... would not be caught - but no style I've seen does that).