Программно определить с помощью ifdef, определена ли метка в модуле перевода - PullRequest
2 голосов
/ 02 апреля 2012

У меня есть следующий бит кода, я ожидаю, что данное cstdio включено, что первая строка будет напечатана, однако вторая строка будет напечатана.

Что я делаю не так?Можно ли узнать, были ли определены метки, такие как printf или strncmp или memcpy, в текущем модуле перевода во время компиляции?

#include <iostream>
#include <cstdio>

int main()
{
   #ifdef printf
      std::cout << "printf is defined.\n";
   #else
      std::cout << "printf NOT defined!\n";
   #endif
   return 0;
}

Причина в том, что препроцессор запускается до того, как переменные и метки вводятся вобласть действия / TU?

Короче говоря, является ли следующий код поддельным?:

http://code.google.com/p/cmockery/source/browse/trunk/src/example/calculator.c#35

Ответы [ 3 ]

6 голосов
/ 02 апреля 2012

#ifdef применяется только к макросам препроцессора, определенным с помощью #define, но не к таким символам, как имена функций и переменные. Вы можете представить себе препроцессор как отдельный отдельный предварительный шаг, например, выполнение кода через Perl-сценарий, который происходит до того, как «настоящий» компилятор добьется успеха.

Таким образом, нет никакого программного способа проверить, определены ли символы, такие как printf, в текущей области. Если вы используете один, и он не определен, вы получите ошибку компилятора. Обычно нужно сделать #include файл заголовка с необходимым определением в исходном файле, на который вы ссылаетесь, а не писать исходный файл, который будет адаптироваться к различным возможным наборам заголовков.

В качестве хака, и в зависимости от вашей среды и конкретной проблемы, заголовочный файл, который определяет printf (или любую функцию, которая вас интересует), может также содержать некоторый препроцессор #define s, который вы можете проверить.

3 голосов
/ 02 апреля 2012

Вы можете использовать элементы защиты из исходных включаемых файлов, чтобы определить, были ли они включены, и, следовательно, функции были объявлены.

Например, <stdio.h>, поставляемый с моим MSVS2010, имеет _INC_STDIO элементы защиты.Таким образом, ваш код должен выглядеть следующим образом:

int main()
{
   #ifdef _INC_STDIO
      std::cout << "printf is defined.\n";
   #else
      std::cout << "printf NOT defined!\n";
   #endif
   return 0;
}

Обратите внимание, что это решение зависит от среды, поэтому вы должны создавать более сложные правила, если вы должны поддерживать более одной цепочки сборки.

2 голосов
/ 02 апреля 2012

Это большое количество символов в stdio.h, которые #define d, и они импортируются cstdio

, поэтому вы можете использовать

#include <iostream>
#include <cstdio>

int main()
{
   #ifdef stdin
      std::cout << "printf is defined.\n";
   #else
      std::cout << "printf NOT defined!\n";
   #endif
   return 0;
}

ПРЕДУПРЕЖДЕНИЕ Я посмотрел на заголовок, но не проверял.

...