I have a macro DDLogDebug(...) and I would like to do the following
#define _DDLogDebug(arg...) DDLogDebug(args)
#undef DDLogDebug
#define DDLogDebug(args...) doSomething(); _DDLogDebug(arg...)
But it does not work. Instead of #define _DDLogDebug(arg...) DDLogDebug(args), I would need a command that "stores" the content of the macro DDLogDebug to _DDLogDebug.
Does something like that exist?
How should one do when one wants to modify a macro whose definition is not exposed?
You can't do something like this with the purely standard preprocessor.
The reason is that macro definition doesn't work like e.g. function definition in the main language: at the time when you define _DDLogDebug, it isn't actually linking to the definition of DDLogDebug - it's storing exactly what you wrote. It won't attempt to actually find an expansion for any names until the macro is being used in the program outside of any definitions. By that point, the definition for DDLogDebug is already gone.
This is actually a valuable and intended behaviour, because it allows the use of techniques like X-macros: one definition can provide a framework and let different calling contexts decide how to actually use it in different ways. Not only is the outer macro not dependent on definitions available at the time it was written, but meaning of its contents can change throughout the program without having to change its structure.
If you can't work around this problem, you might have some luck with the non-standard but widely-supported push_macro and pop_macro directives.
Example of the use of push and pop:
#define FOO 123
#pragma push_macro("FOO")
#undef FOO
FOO
#pragma pop_macro("FOO")
FOO
Run this through gcc -E and you'll see it emits FOO (newline) 123. Works with Clang.
Related
I'm learning about gcc's cleanup attribute, and learning how it calls a function to be run when a variable goes out of scope, and I don't understand why you can use the word "cleanup" with or without underscores. Where is the documentation for, or documentation of, the version with underscores?
The gcc documentation above shows it like this:
__attribute__ ((cleanup(cleanup_function)))
However, most code samples I read, show it like this:
__attribute__ ((__cleanup__(cleanup_function)))
Ex:
http://echorand.me/site/notes/articles/c_cleanup/cleanup_attribute_c.html
http://www.nongnu.org/avr-libc/user-manual/atomic_8h_source.html
Note that the first example link states they are identical, and of course coding it proves this, but how did he know this originally? Where did this come from?
Why the difference? Where is __cleanup__ defined or documented, as opposed to cleanup?
My fundamental problem lies in the fact that I don't know what I don't know, therefore I am trying to expose some of my unknown unknowns so they become known unknowns, until I can study them and make them known knowns.
My thinking is that perhaps there is some globally-applied principle to gcc preprocessor directives, where you can arbitrarily add underscores before or after any of them? -- Or perhaps only some of them? -- Or perhaps it modifies the preprocessor directive or attribute somehow and there are cases where one method, with or without the extra underscores, is preferred over the other?
You are allowed to define a macro cleanup, as it is not a name that is reserved to the compiler. You are not allowed to define one named __cleanup__. This guarantees that your code using __cleanup__ is unaffected by other code (provided that other code behaves, of course).
As https://gcc.gnu.org/onlinedocs/gcc/Attribute-Syntax.html#Attribute-Syntax explains:
You may optionally specify attribute names with __ preceding and following the name. This allows you to use them in header files without being concerned about a possible macro of the same name. For example, you may use the attribute name __noreturn__ instead of noreturn.
(But note that attributes are not preprocessor directives.)
I have a third party piece of code that works differently when I add a macro via Makefile e.g. -DMacro instead of doing #define MACRO in a top level header file
(which as their documentation implies is included in ALL files).
I Googled if there are any differences in defining it in different ways but could not come up with much except Precedence of -D MACRO and #define MACRO.
I am wondering if I am missing anything about make documentation / C standards before I start debugging and determining the issue.
Thanks for any answers.
Usually, it's exactly the same but neither make nor the ISO standard have anything to say about it. It's up to the compiler itself, some may not even have a -D option.
To make, it's just running the command (such as gcc) with whatever options it takes. ISO doesn't specify anything about how to run a compiler, just how the compiler (and the things it creates) behaves.
For gcc, the preprocessor options can be found here so it looks like it is identical to #define.
Is it possible to have a custom availability macro like the __OSX_AVAILABLE_STARTING for instance. I need it to perform in the same way, I just need to change its name and the versions and number of parameters?
Yes, certainly. Objective-C is a strict superset of C, so C macros are very much at your disposal, and that facility is simply a set of C macros that eventually expand to
gcc's __attribute__ keyword to declare special attributes of a function.
The relevant declarations are all in
Availability.h
AvailabilityInternal.h
To refresh, you use the __OSX_AVAILABLE_STARTING macro to tag a function declaration as being supported for a particular version, like this:
extern void mymacfunc() __OSX_AVAILABLE_STARTING(__MAC_10_5,__IPHONE_NA);
So what do we need to implement this ourselves? If you strip their
support for two different OS (mac, iphone), the availability facility boils down to:
A macro that takes a version argument like __MY_AVAILABLE_STARTING(<version>):
#define __MY_AVAILABLE_STARTING(_myversion) __MY_AVAILABILITY_INTERNAL##_myversion
Set of version arguments, like those in Availability.h, that are valid arguments for the above:
#define __MYVER_2_0 20000
#define __MYVER_2_1 20100
#define __MYVER_2_2 20200
#define __MYVER_3_0 30000
Another set of macros, like thos in AvailabilityInternal.h that specifies what should happen for each version (regular support, deprecated, unavailable, weak, etc). Again, this is a function of the compiler, see gcc docs (there are lots of other interesting options):
#define __MY_AVAILABILITY_INTERNAL__MYVER_2_0 __AVAILABILITY_INTERNAL_UNAVAILABLE
#define __MY_AVAILABILITY_INTERNAL__MYVER_2_1 __AVAILABILITY_INTERNAL_WEAK_IMPORT
#define __MY_AVAILABILITY_INTERNAL__MYVER_2_1 __AVAILABILITY_INTERNAL_REGULAR
And finally, where the buck ends, the macros that expand to the __attribute__ facility.
For the ones I have above, you can just keep using Apple's macros:
#define __AVAILABILITY_INTERNAL_DEPRECATED __attribute__((deprecated,visibility("default")))
#define __AVAILABILITY_INTERNAL_UNAVAILABLE __attribute__((unavailable,visibility("default")))
#define __AVAILABILITY_INTERNAL_WEAK_IMPORT __attribute__((weak_import,visibility("default")))
#define __AVAILABILITY_INTERNAL_REGULAR __attribute__((visibility("default")))
Or, of course, you can define your own craziness.
C Macros are powerful stuff, often overlooked. Good luck!
I have a library that has several options defined as this:
#define shouldShowToolbar YES
#define shouldAlignToLeft YES
etc..
and I'm looking for a way to actually replace those from outside (without modifying the library, because the future updates will break it). Is it possible, or am I doomed to change the library source code (which I do have) every time an update comes out.
There is #undef
#include "library_header.h" /* Which defines the macro. */
#undef shouldShowToolbar /* You undef it. */
#define shouldShowToolbar NO /* If you want, you can redefine it. */
http://gcc.gnu.org/onlinedocs/cpp/Undefining-and-Redefining-Macros.html
If you don't want a particular macro to take effect for a section of code and you know that macro name too, you can use
#undef shouldShowToolbar
/* Your code */
#define shouldShowToolbar
This wont totally undef the macro, cos you never know which part of your code might actually want it
These are values that are hardcoded at compile time. If you compile the library with your project then you should be able to redefine them in a file that compiles later in the compile list, I think there is a special keyword for it. Otherwise it is like saying I want to replace YES in the library.
As far as i know, preprocessor directives executes before compilation. So after that, there's no chance to change something.
I want to realize logging in my project.
I have macro, smth like
__LOG_TRACE(lg, expr,...) LOG_TRACE_STREAM(lg) << expr;
So I want to realize interface for this macro - another macro, but I want to support 2 types:
LOG_TRACE(msg);
LOG_TRACE(my_logger, msg);
I have some global logger, and first macro will write msg using global logger.
Second macro will take my_logger and write msg using it.
I can make it with LOG_TRACE(msg, my_logger); - but it's not good, it's harder to read in code. Order of arguments in __LOG_TRACE is not necessary.
Upd:
I don't mean overloading macros.
Look - for example I can do this
#define LOG_TRACE(...) __LOG_TRACE(__VA_ARGS__, current_active)
Now I can write
LOG_TRACE(msg);
LOG_TRACE(msg, logger);
But I want not msg,logger and logger,msg
Macro overloading is not allowed in C or C++. But there are workarounds. Here's an article that will help you "overload" your macro: http://cplusplus.co.il/2010/08/31/overloading-macros/
If you don't have a variable number of loggers, i recommend you to make a macro for each logger. ex (LOG_TRACE_XML, LOG_TRACE_OUT, LOG_TRACE_TXT). Because simpler is better.
But a better way to do this is to have LOG_TRACE_ERROR/ LOG_TRACE_WARNING/ LOG_TRACE_INFO and manage the way these macros behave using IPC or another macro (SET_MODE(XML/TXT/OUT))
You cannot overload pre-processor macros, your compiler will consider this a redeclaration, rather than an overload, and so only the 2nd will be valid.
You should attempt to name your macros differently, both for readability and because that's the only way you'll get the functionality you want.
Why not make it a function + do and stringify expression macro?
#define DO_AND_RETURN_STRING_EXPR(x) (x,#x)
ov(DO_AND_RETURN_STRING_EXPR(y))
ov(my_logger, DO_AND_RETURN_STRING_EXPR(y))
(note I haven't tested this code).
__VA_ARGS__ is an extension to the current C++ standard, but if you are willing to play with this P99 has a lot of utility macros to achieve what you want. In particular macros that implement conditionals according to the number of arguments they are called.
#define LOG_TRACE(...) \
P99_IF_EQ_1(P99_NARG(__VA_ARGS__)) \
(LOG_TRACE_(my_logger, __VA_ARGS__)) \
(LOG_TRACE_(__VA_ARGS__))
P99 is not really C++ compatible, so you'd have to adapt things a bit.
BTW, identifiers that start with _ and a capital letter or another underscore are reserved by C and C++. Double underscores in general are not allowed for C++ because they could interfere with name mangling. So you'd better chose a different name for your base macro.