How do I at compile time undefine a compiler macro using gcc. I tried some compile args to gcc like -D but I can't get to see the "not defined" message.
Thanks
#include <iostream>
#define MYDEF
int main(){
#ifdef MYDEF
std::cout<<"defined\n";
#else
std::cout<<"not defined\n";
#endif
}
You can use the -U option with gcc, but it won't undefine a macro defined in your source code. As far as I know, there's no way to do that.
You should wrap the MYDEF definition in a preprocessor macro, the presence of which (defined on the command line) would then prevent MYDEF from being defined. A bit convoluted to be sure but you can then control the build in the way you want from the command line (or Makefile). Example:
#ifndef DONT_DEFINE_MYDEF
#define MYDEF
#endif
Then from the command line when you don't want MYDEF:
gcc -DDONT_DEFINE_MYDEF ...
http://gcc.gnu.org/onlinedocs/gcc-4.4.2/gcc/Preprocessor-Options.html#Preprocessor-Options
The -U options seemed like what you could have needed... but then again you can't override a definition contained in your source code without resorting to more preprocessor directives.
You can resort to filtering source code and give this back to gcc for compilation, like this pseudo code:
grep -v "define MYDEF" yourFile.c | gcc -o yourFile.o -xc -
Hope it helps.
The code use case is not right. As I see, you have hard coded #define in the file. If compiler initially assumes MYDEF undefined, it will define it once it start processing the file.
You should remove the line #define MYDEF. And I hope your test case will work, if you pass MYDEF to -D and -U.
Here is one possibility that doesn't completely cover your use case but which I found to be helpful in my case.
If your MYDEF were #defined in a separate header file #included from the .c file you could force the definition of the #include guard macro with the -D option (thus preventing the MYDEF #definition) then either actively #define (still with the -D option) MYDEF to something else or just leave it undefined.
It is clear that anything else defined in the header file would also be missing but this was for me a solution to forcedly undefine a macro without changing the third-party code.
Related
I think everybody knows this excellent CMake command:
configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/version.h.cmake
${CMAKE_CURRENT_BINARY_DIR}/version.h
)
But I have to implement that in Makefile. Could you please help me? How to do it?
Configuration file (version.h) is very simple:
#ifndef _VERSION_H_
#define _VERSION_H_
#define VERSION_MAJOR #VERSION_MAJOR#
#define VERSION_MINOR #VERSION_MINOR#
#define VERSION_BUILD #VERSION_BUILD#
#define VERSION_REVISION #VERSION_REVISION#
#endif // _VERSION_H_
This won't work. Well it might be, but it will be a hassle. These config.h files are made to communicate the result from a configure tool (configure from Autotools, CMake etc.) to the compiler.
When you use Makefiles, you can simply attach necessary flags or variables to the C(++) compiler call (with -D). There is no need to add the complexity of a config.h.
Is there a way I can run gcc -E to run the preprocessor but also to keep the #define, #include, other directives in the output (possibly as comments)? I thought I remembered seeing an option for this but I can't find it in the GCC Preprocessor Options page. I need this to track down where things are going wrong in a complex case involving lots of include files and macros.
The relevant options are listed under -dCHARS. -dD outputs macro definitions (both #define and #undef directives), -dI outputs #include directives, and they can be combined to -dDI.
Using GCC under Windows, I would like to be able to specify on the gcc command line (or from a manually managed makefile) the name of a specific include file to be included in the file being compiled. As I see it, ideally the source code file would contain a line something like…
#include INCLUDEFILENAME
…then a filename specified on the gcc command line would be substituted for the INCLUDEFILENAME text.
It seems I can get close to achieving this by defining a macro called INCLUDEFILENAME on the gcc command line using the -D option (eg. -D INCLUDEFILENAME="C:\TestLib\Test1.h") but when the filename text gets substituted into the #include statement it is not enclosed in double quotes, and without these it is not recognized as a file to be included. Of course…
#include "INCLUDEFILENAME"
…doesn’t work as INCLUDEFILENAME then becomes a string literal and does not get replaced by the macro value. I have tried other ways of specifying the double quotes (\x22, \", "\"", etc) but these don’t seem to work on the #include line.
I am aware of the gcc -include option which it seems can force a file to be included without it being mentioned in any way in the source file, but I would prefer that the source file indicates that an include file is to be included here but that it’s name is specified “externally” to the source file (ultimately, from the makefile).
Any suggestions on how I can achieve this would be appreciated.
You have to include the double quotes " as part of the define (or <>, as the case may be):
% cat test.c
#include <stdio.h>
#include OTHERFILE
int main() { printf("%s\n", func()); }
% cat func.c
char *func() { return "It worked."; }
% gcc test.c -DOTHERFILE='"func.c"'
% ./a.out
It worked.
%
You can use the ugly but classic stringification trick:
#define STRINGIFY2(x) #x
#define STRINGIFY(x) STRINGIFY2(x)
#include STRINGIFY(INCLUDEFILENAME)
I have some C source files that need to be pre-processed so that I can use another application to add Code Coverage instrumentation code in my file.
To do so, I use GCC (I'm using this on a LEON2 processor so it's a bit modified but it's essentially GCC 3.4.4) with the following command line:
sparc-elf-gcc -DUNIT_TEST -I. ../Tested_Code/0_BSW/PKG_CMD/MEMORY.c -E > MEMORY.i
With a standard file this works perfectly, but this one the programmer used a #ifndef UNIT_TEST close and no matter what I do the code won't be pre-processed. I don't understand why since I'm passing -DUNIT_TEST to GCC explicitly defining it.
Does anyone have any clue what could cause this? I checked the resulting .i file and as expected my UNIT_TEST code is not present in it so I get an error when instrumenting it.
Anything wrapped in an #ifndef will only be parsed if it's NOT defined so you need to remove that definition to get all the code that is inside that block. GCC can't spit out preprocessed info for all the #ifdef and #ifndef if at preprocessing times symbols are/aren't defined.
I'm using tempnam() only to get the directory name, so this security warning does not apply to my case. How can I disable it? I couldn't find any switches to do it.
If you really only want the directory name, use the string constant macro P_tmpdir, defined in <stdio.h>.
"The tempnam() function returns a pointer to a string that is a valid filename, and such that a file with this name did not exist when tempnam() checked."
The warning arises because of the race condition between checking and a later creating of the file.
You want to only get the directory name? What should that be good for?
Like stranger already said, you may disable this (and similar warnings) using -Wno-deprecated-declarations.
The answer is no, because - on many systems - the GNU C library (glibc) which implements this function is compiled so as to trigger a linker warnings when it is used.
See:
GCC bug page regarding this issue - I filed this a short while ago.
GNU ld bug page regarding this issue - filed in 2010!
GNU ld bug page suggesting an approach for resolving the issue - I filed this a short while ago.
Note that the problem is not specific to GCC - any linker is supposed to emit this warning, its trigger is "hard-coded" in the compiled library.
If you want to create a temporary directory that's unique for the process, you can use mkdtemp.
This can, e.g., be useful to create FIFOs in there, or when a program needs to create lots of temporary files or trees of directories and files: Then they can be put into that directory.
As linker warning it may be obfuscated by using this answer's ASM workaround/hack:
https://stackoverflow.com/a/29205123/2550395
Something like this (quick and dirty):
#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
char my_file[20];
#define __hide_section_warning(section_string) \
__asm__ (".section " section_string "\n.string \"\rquidquid agis prudenter agas et respice finem \"\n\t.previous");
/* If you want to hide the linker's output */
#define hide_warning(symbol) \
__hide_section_warning (".gnu.warning." #symbol)
hide_warning(tmpnam)
tmpnam( my_file );
lock_fd = open( my_file, O_CREAT | O_WRONLY, (S_IRUSR | S_IWUSR | S_IRGRP) );
However, it still will leave a trace in the Make.p file and therefore isn't perfectly clean, besides already being a hack.
PS: It works on my machine ¯\_(ツ)_/¯
You can use GCC's -Wno-deprecated-declarations option to disable all warnings like this. I suggest you handle the warning properly, though, and take the suggestion of the compiler.