简体   繁体   中英

Expand C preprocessor ternary macro for printing in pragma message?

Judging by this Print numeric value of a define that's based on other macros via pragma message? , what I want is likely not possible; then again, I'm not doing arithmetic here - so here is my example:

#include <stdio.h>
enum my_sizes { SIZE_BITS_8 = 0, SIZE_BITS_16 = 1, SIZE_BITS_32 = 2 };

#define XSTR(x) STR(x)
#define STR(x) #x

#define CHOSEN_SIZE_BITS SIZE_BITS_32
#define CHOSEN_SIZE_BYTES \
    ( CHOSEN_SIZE_BITS==SIZE_BITS_8 ? 1  \
      : CHOSEN_SIZE_BITS==SIZE_BITS_16 ? 2 \
      : CHOSEN_SIZE_BITS==SIZE_BITS_32 ? 4 \
      : 0 )

#pragma message( "CHOSEN_SIZE_BITS " XSTR(CHOSEN_SIZE_BITS) " CHOSEN_SIZE_BYTES " XSTR(CHOSEN_SIZE_BYTES) )

int main() {
    printf("Hello, world! bytes: %d!\r\n", CHOSEN_SIZE_BYTES);
    return 0;
}

In https://replit.com/languages/c , this produces:

> clang-7 -pthread -lm -o main main.c
main.c:14:9: warning: CHOSEN_SIZE_BITS SIZE_BITS_32
      CHOSEN_SIZE_BYTES ( SIZE_BITS_32==SIZE_BITS_8 ? 1 :
      SIZE_BITS_32==SIZE_BITS_16 ? 2 :
      SIZE_BITS_32==SIZE_BITS_32 ? 4 : 0 )
      [-W#pragma-messages]
#pragma message( "CHOSEN_SIZE_BITS " XSTR(CHOSEN_SIZE_...
        ^
1 warning generated.
> ./main
Hello, world! bytes: 4!
> 

What I wanted instead, was the printout of pragma message to be:

main.c:14:9: warning: CHOSEN_SIZE_BITS 2 CHOSEN_SIZE_BYTES 4

Note that XSTR would have expanded CHOSEN_SIZE_BITS to a number, in case it was defined via #define CHOSEN_SIZE_BITS 2 , but it seemingly doesn't if an enum value is used in the define; and of course, the whole ternary expression is included in the pragma message printout - even if the C printout (via printf ) confirms that the CHOSEN_SIZE_BYTES does indeed end up with the expected value 4.

So, is it somehow possible to get the printout that I want from the above macros - and if so, how?

To calculate something in preprocessor you have to calculate it in preprocessor. Ternary is evaluated at runtime. In preprocessor you have macro expansions and ## operator and then some more macro expansions and ## operator. Nothing more.

The following code:

#define SIZE_BITS_8   0
#define SIZE_BITS_16  1
#define SIZE_BITS_32  2

#define XSTR(x) STR(x)
#define STR(x) #x

#define BITS_TO_BYTE_0()  1
#define BITS_TO_BYTE_1()  2
#define BITS_TO_BYTE_2()  4
#define BITS_TO_BYTE_IN(SIZE_BITS)  \
        BITS_TO_BYTE_##SIZE_BITS()
#define BITS_TO_BYTE(SIZE_BITS)  \
        BITS_TO_BYTE_IN(SIZE_BITS)


#define CHOSEN_SIZE_BITS   SIZE_BITS_32
#define CHOSEN_SIZE_BYTES  BITS_TO_BYTE(CHOSEN_SIZE_BITS)

#pragma message( "CHOSEN_SIZE_BITS " XSTR(CHOSEN_SIZE_BITS) " CHOSEN_SIZE_BYTES " XSTR(CHOSEN_SIZE_BYTES) )

Outputs the following diagnostic on GCC:

<source>:22:9: note: '#pragma message: CHOSEN_SIZE_BITS 2 CHOSEN_SIZE_BYTES 4'
   22 | #pragma message( "CHOSEN_SIZE_BITS " XSTR(CHOSEN_SIZE_BITS) " CHOSEN_SIZE_BYTES " XSTR(CHOSEN_SIZE_BYTES) )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM