2015-10-06 2 views
-1

Я пытаюсь использовать код ниже, используя компиляторы MSVC 2013 и GCC.C строка, чтобы сохранить определение макроса

#define AV_FFMPEG_SAMPLE(...)# __VA_ARGS__ 

const char *function_store = AV_FFMPEG_SAMPLE(

#define BUF_SIZE 65536 
#define ALIGN_MASK 0xFF00 

int foo() 
{ 
    int abc; 
    int *xyz; 

    xyz = (int *)malloc(BUF_SIZE); 
    return (BUF_SIZE & ALIGN_MASK); 
} 
); 

int main(int argc, char **argv) 
{ 
    printf("%s\n", function_store); 
} 

MSVC 2013 Выход:

#define BUF_SIZE 65536 #define ALIGN_MASK 0xFF00 INT Foo() {INT аЬс; int * xyz; xyz = (int *) malloc (BUF_SIZE); return (BUF_SIZE & ALIGN_MASK); }

НКУ Выход:

INT Foo() {INT аЬс; int * xyz; xyz = (int *) malloc (BUF_SIZE); return (BUF_SIZE & ALIGN_MASK); }

Я предпочитаю выход такой же, как выход MSVC 2013, но мне нужно, чтобы получить то же самое, используя GCC (MinGW). Как я могу получить результат, похожий на вывод MSVC 2013, используя GCC (MinGW)?

+0

Возможно, переместите определения макросов из скобок. – Downvoter

+1

Это выглядит как хороший пример того, как ** не ** использовать макросы. Вы не можете использовать расширение '# define' внутри макроса. '#' не должен находиться за именем макроса/скобкой. Вы лучше заявите, чего хотите достичь. Это может привести к XY-проблеме. MSVC даже не совместим с C99, не говоря уже о текущем стандарте C11. – Olaf

+1

О, и: Не произносите результат 'malloc' & friends в C! – Olaf

ответ

1

C определяет функции типа вызова макроса, который

Если есть последовательности предварительной обработки маркеров в списке аргументов, которые могли бы выступать в качестве директив препроцессора, поведение не определено.

(C 2011 6.10.3/11, идентичный C99 6.10.3/11).

Это именно ваша ситуация. Так как строковое кодирование применяется только в контексте списка замены макроподобных макросов, и поведение (явно) не определено для случая, когда аргументы макроса содержат токены, которые в противном случае составляли бы директивы предварительной обработки, вы в значительной степени на произвол судьбы любого компилятора твой выбор. Нет надежного способа добиться того, что вы хотите сказать.

Если вы хотите, чтобы результат был согласованным, независимо от того, какой компилятор строит ваш код, а затем переместите определения макросов из области действия AV_FFMPEG_SAMPLE().

Откровенно говоря, хотя я не очень-то отношусь к VS 2013 с точки зрения соответствия стандартам, я склонен думать более высоко о GCC. Не предупреждает ли он о вашем коде?

+0

Джон, я ценю ваш ответ. Но моя цель - сохранить макроопределения также как часть C-строки.Если я переведу свои макроопределения «вне сферы действия вызова AV_FFMPEG_SAMPLE()», то я не могу достичь того, что хотел. В моем случае эта C-строка получает некоторый другой компилятор и пытается скомпилировать. Поскольку макроопределения уходят от первого компилятора, строка получает разорванную до того, как будет передана второму компилятору. Когда второй компилятор пытается скомпилировать прошедшую C-строку, он не работает из-за отсутствия макроопределений. – ARK

+0

@ARK, тогда вы не можете достичь того, что хотите, периода, если вам не повезет с выбранным компилятором. Компиляторы не обязаны даже принимать ваш код вообще. Если они действительно согласны с этим, они не обязаны делать с ним какую-либо особую вещь и не всегда делают то же самое с этим. Поведение * undefined *. –

Смежные вопросы