Определить расширение макроса C - PullRequest
0 голосов
/ 03 июля 2018

Есть ли способ определить «окончательное значение» расширенного макроса C, проверяя скомпилированный объект или запуская некоторую форму gcc -E в файле .c или .h?

test.h

#define AAA 1
#define BBB 10
#define CCC (AAA+BBB)

test.c

#include <stdio.h>
#include "test.h"

int main(){
   printf("%d\n", CCC);
   return 0;
}

Таким образом, есть ли способ получить расширенное значение:

#define CCC 11

или

#define CCC (1+10)

Если скомпилировано с

gcc -dM -E test.c | grep CCC 

или

gcc -dD -E test.c | grep CCC

выходы

#define CCC (AAA+BBB)

, что требует, чтобы я все еще знал, что такое AAA и BBB.

Скомпилировано с:

gcc -E test.c

Дает (пропуская шаблон):

# 4 "test.c"
int main(){
printf("%d\n", (1+10));
return 0;
}   

В то время как оно расширено CCC Я теперь потерял отображение обратно к CCC.

Edit: Поскольку было неясно, что я хотел бы как-то определить, что такое CCC (либо 11, либо 1 + 10 (как пример gcc -E показал, что он вставлен только (1 + 10), а не 11), предпочтительно без изменения самого кода Printf было плохой идеей для использования в MRE, на самом деле я имел в виду такой код:

struct my_struct {
    int my_array[CCC]
    ... other stuff ...
}

Вопрос в том, насколько велика my_array, поэтому я могу создать структуру на другом языке (python через ctypes) и узнать, сколько места мне нужно. Я знаю, что для структур я могу использовать pahole, но надеялся сделать это только с gcc и в более общем случае (скажем, глобальный массив не в структуре).

Ответы [ 2 ]

0 голосов
/ 03 июля 2018

Препроцессор никогда не создаст

#define CCC (1+10)

Расширение CCC всегда (AAA+BBB); просто результат расширения макроса повторно сканируется для расширения других макросов, и в этот момент AAA и BBB превращаются в 1 и 10 соответственно.

Возможно, более ясным примером этого является

#define AAA 1
#define CCC AAA
#define AAA "hello"

size_t x = sizeof CCC;

Этот код будет расширен до "hello", а не 1. CCC всегда имеет значение AAA; просто к моменту обработки size_t x = sizeof CCC; само AAA превратится в "hello".

Этот пример также демонстрирует, что макросы могут быть переопределены, поэтому может даже не быть единственного ответа на вопрос «каково значение CCC?».

Вот почему нет простого вызова или переключения компилятора; то, что вы хотите, просто не существует.

Тем не менее, если вы можете использовать пользовательский код, вы можете просто запустить, например,

#define AAA 1
#define BBB 10
#define CCC (AAA+BBB)
CCC

- gcc -P -E, и результат будет (1+10).

0 голосов
/ 03 июля 2018
#include <stdio.h>

#define AAA 1
#define BBB 2
#define CCC (AAA+BBB)

#define STRINGIFY(x) #x
#define PASTE(x) STRINGIFY(x)


int main(void)
{
  printf("CCC = '%s'\n", PASTE(CCC));
}

печать

CCC = '(1+10)'

Альтернативная версия, печатающая то же самое:

#include <stdio.h>

#define AAA 1
#define BBB 2
#define CCC (AAA+BBB)

#define STRINGIFY(x) #x
#define INTERMEDIATE(x) #x " = '" STRINGIFY(x) "'"

int main(void)
{
  printf("%s\n", INTERMEDIATE(CCC));
}
...