Условное макрорасширение

Возглавляет: Это - странный вопрос.

У меня есть некоторые действительно полезные макросы, которые мне нравится использовать для упрощения некоторого входа. Например, я могу сделать Log(@"My message with arguments: %@, %@, %@", @"arg1", @"arg2", @"arg3"), и это будет расширено в более сложный вызов метода, который включает вещи как self, _cmd, __FILE__, __LINE__, и т.д., так, чтобы я могу легко отследить, где вещи становятся зарегистрированными. Это работает отлично.

Теперь я хотел бы расшириться, мои макросы к не только работают с методами Objective C, но и функциями генерала C. Проблема self и _cmd части, которые находятся в макрорасширении. Эти два параметра не существуют в функциях C. Идеально, я хотел бы смочь использовать этот тот же набор макросов в функциях C, но я сталкиваюсь с проблемами. Когда я использую (например), мой Log() макрос, я получаю предупреждения компилятора о self и _cmd будучи необъявленным (который имеет общий смысл).

Моя первая мысль состояла в том, чтобы сделать что-то как следующее (в моем макросе):

if (thisFunctionIsACFunction) {
  DoLogging(nil, nil, format, ##__VA_ARGS__);
} else {
  DoLogging(self, _cmd, format, ##__VA_ARGS__);
}

Это все еще производит предупреждения компилятора, начиная со всего, если () оператором заменяют вместо макроса, приводящего к ошибкам с self и _cmd ключевые слова (даже при том, что они никогда не будут выполняться во время функционального выполнения).

Моя следующая мысль состояла в том, чтобы сделать что-то вроде этого (в моем макросе):

if (thisFunctionIsACFunction) {
  #define SELF nil
  #define CMD nil
} else {
  #define SELF self
  #define CMD _cmd
}
DoLogging(SELF, CMD, format, ##__VA_ARGS__);

Это не работает, к сожалению. Я получаю "ошибку: '#' не сопровождается макро-параметром" на моем первом #define.

Моя другая мысль состояла в том, чтобы создать второй набор макросов, специально для использования в функциях C. Это сильно пахнет плохим запахом кода, и я действительно не хочу делать это.

Есть ли некоторый способ, которым я могу использовать тот же набор макросов и из методов Objective C и из функций C и только ссылки self и _cmd если макрос находится в методе Objective C?

редактирование больше информации:

thisFunctionIsACFunction определяется довольно элементарным способом (и я определенно открыт для улучшений и предложений). В основном это - это:

BOOL thisFunctionIsACFunction == (__PRETTY_FUNCTION__[0] != '-' && __PRETTY_FUNCTION__[0] != '+');

Это полагается на поведение компилятора для предварительного ожидания '-' или '+', например, и методы класса для объектов Objective C. Что-либо еще должно быть функцией C (так как функции C не могут иметь имен, которые начинаются с '-' или '+').

Я понимаю, что эта проверка является технически проверкой на этапе выполнения с тех пор __PRETTY_FUNCTION__ заменяется a char*, и это - вероятно, главный контрольно-пропускной пункт к моему запросу на справку.

7
задан Dave DeLong 13 June 2010 в 05:59
поделиться

2 ответа

Препроцессор выполняет всю свою работу до разбора реального кода. Препроцессор не может знать, является ли функция C или obj-C, потому что он работает до разбора кода.

По той же причине,

if (thisFunctionIsACFunction) {
  #define SELF nil
  #define CMD nil
} else {
  #define SELF self
  #define CMD _cmd
}
DoLogging(SELF, CMD, format, ##__VA_ARGS__);

не может работать #defines - они обрабатываются до этапа компиляции.

Таким образом, сам код должен содержать "runtime" проверку (хотя компилятор может оптимизировать ее).

Я бы предложил определять что-то вроде

void *self = nil; //not sure about the types that
SEL _cmd = nil;   //would be valid for obj-c

в глобальной области видимости; функции C будут "видеть" эти определения, а методы Objective-C, надеюсь, скроют их своими собственными определениями.

7
ответ дан 7 December 2019 в 05:18
поделиться

Вы можете использовать что-то вроде условного макроса:

#ifndef OBJECTIVE_C
  #define self 0
  #define _cmd ""
#endif

Я не совсем уверен, что вы должны определить self и _cmd , чтобы эти были только догадки.

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

0
ответ дан 7 December 2019 в 05:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: