This question already has answers here:
The ## operator in C
(7 answers)
Closed 4 years ago.
something like #NAME or ##NAME. what do they mean in C? I saw them in GCC documents about macro.
operator ## concatenates two arguments leaving no blank spaces between them..
#define printe(a,b) a ## b
printe(c,out) << "testing";
output is : testing
and single # is used for parameter replacement withe the string parameter
like
#define st(x) #x
cout<<st(tesing); // equivalent to cout<<"testing";
and # is also a preprocessor directive..
A code statement beginning with # indicates what follows is a preprocessor directive and should be expanded by the pre-processor.
## is called token Pasting or Token concatenation macro.
From the wikipedia page describing the C preprocessor:
The ## operator concatenates two tokens into one token, as in this example:
#define DECLARE_STRUCT_TYPE(name) typedef struct name##_s name##_t
DECLARE_STRUCT_TYPE(g_object); // Outputs typedef struct g_object_s g_object_t;
The # operator signals other directives to the C preprocessor, for example: #include, #define, #undef, #error, #if, #ifdef, #ifndef, #else, #elif, #endif
The '#' is really not an operator, they are preprocessor directives, and the '##' is used only for function macro definitions.
There are many preprocessor directives in C:
For Macro Definitions there are:
#define
#undef
For Conditional Inclusions, there are:
#ifdef
#ifndef
#if
#endif
#else
#elif
For Line Control, there is:
#line
For Error, there is:
#error
For Source file inclusion, there is:
#include
For Pragma directive, there is:
#pragma
For more information, read this http://www.cplusplus.com/doc/tutorial/preprocessor/
Related
I have these definitions in a project_conf.h file
#define MCU 16F628
#define MCU_HEADER_FILE MCU##.h
And I want to implement a macro that would substitute this line
#include <MCU_HEADER_FILE>
with just
CALL_MUC_HEADER_FILE
These <> things I dont know how to handle.
Apart that you can't effectively define macro, that contains #include directive, that is something like:
#define FOO #include <foo.h>
there is another issue with these macro definitions:
#define MCU 16F628
#define MCU_HEADER_FILE MCU##.h
The second object-like macro is invalid, since it does not produce valid preprocessing token. The ## operator concatenates token MCU (not even expanding it) with ., which combines into MCU., invoking an undefined behavior.
Regarding to C11 (N1570) ยง6.10.3.3/p3 The ## operator:
If the result is not a valid preprocessing token, the behavior is
undefined.
For instance, GCC compiler has diagnostic message in such case, when you run it with -E flag:
check.c:7:1: error: pasting "MCU" and "." does not give a valid
preprocessing token
You can also see from here, that MCU was not expanded into its text replacement.
The valid solution would be to get rid off ## operator at all and apply third, less-known form of #include directive:
# include pp-tokens new-line
Here is one possible way:
#define MCU_HEADER <MCU.h> // MCU will be expanded into 16F628
#include MCU_HEADER
But as stated above it best what you can do with #define directive as is.
It looks that you are thinking too complicated.
The tokens after an #include directive are simply expanded, you don't need to do any macro concatenation magic with it:
#define incFile(A) A.h
#define hoho(X) <incFile(X)>
#include hoho(string)
Note: the MCU_HEADER_FILE definition should be changed to include the < and > on either side
#define GLUE_IMPL(A, B) A##B
#define GLUE(A, B) GLUE_IMPL(A, B)
#define MCU 16F628
#define MCU_HEADER_FILE GLUE(GLUE(GLUE(<, MCU),.h), >)
#include MCU_HEADER_FILE
You can't put anything in a #define statement that begins with a # (#include, #if, #endif e.t.c.), so #include MCU_HEADER_FILE is the best you can get.
Suppose I have this code:
#define NAME MY_APP
#define ENABLE NAME ## _ENABLE
I want to check if the macro that ENABLE expands to is defined, i.e., if MY_APP_ENABLE is defined. Is this possible using C macros?
You can use the construct defined to check if a macro is defined, but it's only possible to use this in preprocessor expressions. It's possible to write a macro that expands to this construct. For example:
#define MY_APP_ENABLED
#define IS_DEFINED(x) defined(x ## _ENABLED)
#if IS_DEFINED(MY_APP)
#error "YES"
#else
#error "NO"
#endif
The above will issue YES when compiled. If MY_APP_ENABLED isn't defined, NO will be issued.
Update: The following version will work when NAME is defined to MY_APP. The extra level of indirections allows NAME to be expanded to MY_APP before it's concatenated with _ENABLED:
#define MY_APP_ENABLED
#define IS_DEFINED0(x) defined(x ## _ENABLED)
#define IS_DEFINED(x) IS_DEFINED0(x)
#define NAME MY_APP
#if IS_DEFINED(NAME)
#error "YES"
#else
#error "NO"
#endif
No. In particular, the suggested
#ifdef NAME ## _ENABLE
will not work, according to 6.10.3.4 Rescanning and further replacement, which says
The resulting completely macro-replaced preprocessing token sequence is not reprocessed as a preprocessing directive even if it resembles one, but all pragma unary operator expressions within it are then processed as specified in 6.10.9 below.
I have concrete_impl.h (as is):
#ifdef TUPLE_ITERATOR_WITH_INDEX
#define TUPLE_ITERATOR TUPLE_ITERATOR_NO_INDEX
#define iterate_tuple_fname iterate_tuple_id
#else
#define TUPLE_ITERATOR TUPLE_ITERATOR_INDEX
#define iterate_tuple_fname iterate_tuple
#endif
#undef iterate_tuple_fname_back
#define iterate_tuple_fname_back iterate_tuple_fname##_back
static void iterate_tuple_fname() // ok
{
}
static void iterate_tuple_fname_back() // redefinition error
{
}
And concrete.h (as is):
#ifndef CONCRETE_H
#define CONCRETE_H
#define TUPLE_ITERATOR_WITH_INDEX
#include "concrete_impl.h"
#undef TUPLE_ITERATOR_WITH_INDEX
#include "concrete_impl.h"
#endif // CONCRETE_H
What I want to get - is 4 functions:
iterate_tuple
iterate_tuple_id
iterate_tuple_back
iterate_tuple_id_back
But on "_back" functions I have redefinition error. Why?
iterate_tuple_fname##_back is nothing else than iterate_tuple_fname_back. To have iterate_tuple_fname replaced by its macro replacement list, you'll need a helper macro:
#define CONCAT(a, b) a ## b
#define iterate_tuple_fname_back CONCAT(iterate_tuple_fname, _back)
UPDATE: Sorry, have forgotten all about C after several years of C# programming.
It actually needs double run through helper macros:
#define CONCAT1(a, b) a ## b
#define CONCAT(a, b) CONCAT1(a, b)
#define iterate_tuple_fname_back CONCAT(iterate_tuple_fname, _back)
Apparently you misunderstand how the ## operator works.
If the preprocessing token adjacent to the ## operator is a parameter of the current macro, then this parameter is recursively analyzed for further replacement first, and the result of that replacement substituted into the result.
If the preprocessing token adjacent to the ## operator is not a parameter of the current macro, then recursive analysis and replacement of that token does not take place. The token is simply concatenated with the other token.
Later, once all parameters are substituted and all concatenations are joined, the entire result is rescanned again for further replacements. But then it is already be too late for your example.
In your case you defined this macro
#define iterate_tuple_fname_back iterate_tuple_fname##_back
Since iterate_tuple_fname is not a parameter of this macro, no early replacement occurs for iterate_tuple_fname. The whole thing is immediately concatenated into iterate_tuple_fname_back and only after that it is rescanned. But rescan finds nothing to replace there, so iterate_tuple_fname_back is the final result.
If you want the preprocessor to replace the left-hand side of the ## operator (which was your intent apparently), you absolutely have to use a macro parameter on the left-hand side, as in
#define ITF_back(prefix) prefix##_back
and then you can use this macro as
ITF_back(iterate_tuple_fname)
Now the rescan and recursive replacement inside iterate_tuple_fname will occur early, before the concatenation with the _back part. I.e. it will work as you wanted it to.
Is there a '#' operator in C ?
If yes then in the code
enum {ALPS, ANDES, HIMALYAS};
what would the following return ?
#ALPS
The C language does not have an # operator, but the pre-processor (the program that handles #include and #define) does. The pre-processor simple makes #ALPS into the string "ALPS".
However, this "stringify" operator can only be used in the #define pre-processor directive. For example:
#define MAKE_STRING_OF_IDENTIFIER(x) #x
char alps[] = MAKE_STRING_OF_IDENTIFIER(ALPS);
The pre-processor will convert the above example into the following:
char alps[] = "ALPS";
There is no # operator in C. The # prefix is used to delineate preprocessor instructions.
See: http://en.wikipedia.org/wiki/C_preprocessor
No. # is used for preprocessor directives, such as #include and #define. It can also be used inside macro definitions to prevent macro expansion.
The sharp symbol in C is the prefix for the preprocessor directives.
It is not an operator ...
"#" isn't an operator in C.
But The preprocessor (which operates before the compiler) provides the ability for
_ the inclusion of header files :
enter code here#include
_ macro expansions : **#define foo(x) bar x**
_ conditional compilation :
**#if DLEVEL > 5
#define STACK 200
#else
#define STACK 50
#endif
#endif**
In enum {ALPS, ANDES, HIMALYAS};
Nothing would return ALPS. You've just defined a strong integer type (ALPS = 0, ANDES = 1 and HIMALYAS = 2), but it's useles without a name to this enumreation like this :
enum mountain {ALPS, ANDES, HIMALYAS};
I want to stringify the result of a macro expansion.
I've tried with the following:
#define QUOTE(str) #str
#define TEST thisisatest
#define TESTE QUOTE(TEST)
And TESTE gets expanded to: "TEST", while I'm trying to get "thisisatest". I know this is the correct behavior of the preprocessor but can anyone help me with a way to achieve the other one?
Using TESTE #TEST is not valid
Using TESTE QUOTE(thisisatest) is not what I'm trying to do
Like this:
#include <stdio.h>
#define QUOTE(str) #str
#define EXPAND_AND_QUOTE(str) QUOTE(str)
#define TEST thisisatest
#define TESTE EXPAND_AND_QUOTE(TEST)
int main() {
printf(TESTE);
}
The reason is that when macro arguments are substituted into the macro body, they are expanded unless they appear with the # or ## preprocessor operators in that macro. So, str (with value TEST in your code) isn't expanded in QUOTE, but it is expanded in EXPAND_AND_QUOTE.
To clarify a bit more, essentially the preprocessor was made to execute another "stage". i.e :
1st case:
->TESTE
->QUOTE(TEST) # preprocessor encounters QUOTE
# first so it expands it *without expanding its argument*
# as the '#' symbol is used
->TEST
2nd case:
->TESTE
->EXPAND_AND_QUOTE(TEST)
->QUOTE(thisisatest)
# after expanding EXPAND_AND_QUOTE
# in the previous line
# the preprocessor checked for more macros
# to expand, it found TEST and expanded it
# to 'thisisatest'
->thisisatest