2016-02-11 3 views
2

Я искал немного кода, для которого требуется определенная версия OpenSSL. Если номер версии, экспортируемый OpenSSL, недостаточно высок, возвращается предупреждение, и различные биты программы отключены.Строковая интерполяция в предупреждениях/сообщениях препроцессора C

код выглядит следующим образом:

#if OPENSSL_VERSION_NUMBER >= 0x10002000 
     //code here 
#else 
#warning "http_auth_ldap: Compiling with OpenSSL < 1.0.2, certificate verification will be unavailable" 

Теперь, говорит, что я хотел включить заявленный номер версии в этом сообщении на благо пользователя.

docs for CPP говорят, что:

Ни #error, ни #warning макро расширяет свой аргумент. Внутренние последовательности пробелов заменяются на единое пространство. Строка должна состоять из полных токенов. Мудрее сделать аргумент этих директив единственной строковой константой; это позволяет избежать проблем с апострофами и т. п.

Это, как представляется, мешает мне просто вставить #OPENSSL_VERISON_NUMBER в конец сообщения.

Автор этого бита кода попробовал метод stringification detailed in this question, но это, кажется, не работает:

#// used for manual warnings 
#define XSTR(x) STR(x) 
#define STR(x) #x 

Это приводит к чтению предупреждения:

warning: http_auth_ldap: Compiling with OpenSSL < 1.0.2, certificate verification will be unavailable. OPENSSL_VERSION_NUMBER == OPENSSL_VERSION_NUMBER [-W#pragma-messages]

..и сбой сборки. #pragma message, по-видимому, страдает от того же ограничения не-макрорасширения, что и #warning.

Есть ли разумный способ связать строку версии с ошибкой?

+1

В основном потому, что это чужой код, который я пытаюсь понять. Я получаю это предупреждение, но я не вижу, что он сравнивает и не пытается определить, является ли это проблемой синтаксиса или проблемой в моей среде сборки. –

+0

В стандартном препроцессоре C нет '# предупреждения'. Это расширение, предлагаемое gcc. Стандарт не предоставляет способ создания диагностических сообщений, подобных этому. –

+0

@ MikeyT.K .: Извините, не смог удержаться :-) Хорошо, что вы его нашли, но почему бы не просто изменить 'o' на' e' (mitted)? – Olaf

ответ

1

С #warrning не является переносным, вы можете попытаться использовать другие вещи, которые вы знаете о своей реализации.

#define cat(a,b) cat2(a,b) 
#define cat2(a,b) a##b 

#define FOO 199 
#define REQUIRED_FOO 200 
#if FOO < REQUIRED_FOO 

void cat(cat(FOO_is_, FOO), 
    cat(_required_FOO_is_, REQUIRED_FOO))() 
{ 
    #warning Busted! 
} 

#endif 

Demo.

Здесь я использую тот факт, что gcc печатает имя функции (после макрорасширения!), Где происходит ошибка или предупреждение.