Heads up: Esta es una pregunta extraña.Expansión de macro condicional
Tengo algunas macros realmente útiles que me gusta usar para simplificar algunos registros. Por ejemplo, puedo hacer Log(@"My message with arguments: %@, %@, %@", @"arg1", @"arg2", @"arg3")
, y eso se ampliará a una invocación de método más complejo que incluye cosas como self
, _cmd
, __FILE__
, __LINE__
, etc., de modo que pueda rastrear fácilmente dónde se registran las cosas. Esto funciona genial
Ahora me gustaría expandir mis macros no solo para trabajar con métodos Objective-C, sino también con funciones C generales. El problema son las porciones self
y _cmd
que se encuentran en la expansión de macros. Estos dos parámetros no existen en las funciones C. Idealmente, me gustaría poder usar este mismo conjunto de macros dentro de las funciones C, pero estoy teniendo problemas. Cuando uso (por ejemplo) mi macro Log()
, recibo advertencias del compilador acerca de self
y _cmd
no declaradas (lo que tiene sentido).
Mi primera idea era hacer algo como lo siguiente (en mi macro):
if (thisFunctionIsACFunction) {
DoLogging(nil, nil, format, ##__VA_ARGS__);
} else {
DoLogging(self, _cmd, format, ##__VA_ARGS__);
}
Esto todavía produce advertencias del compilador, ya que toda la instrucción if() se sustituye en lugar de la macro, lo que resulta en errores con las palabras clave self
y _cmd
(aunque nunca se ejecutarán durante la ejecución de la función).
Mi siguiente pensamiento fue a hacer algo como esto (en mi macro):
if (thisFunctionIsACFunction) {
#define SELF nil
#define CMD nil
} else {
#define SELF self
#define CMD _cmd
}
DoLogging(SELF, CMD, format, ##__VA_ARGS__);
eso no funciona, por desgracia. Me sale "error: '#' no es seguido por un parámetro de macro" en mi primer #define
.
Mi otro pensamiento fue crear un segundo conjunto de macros, específicamente para usar en funciones C. Esto apesta a un mal olor de código, y yo realmente no quiero hacer esto.
¿Hay alguna manera en que pueda usar el mismo conjunto de macros desde ambos métodos Objective-C y C, y solo haga referencia a self
y _cmd
si la macro está en un método Objective-C?
edición más información:
thisFunctionIsACFunction
se determina de una manera bastante rudimentario (y yo soy definitivamente abierto a mejoras y sugerencias). Básicamente se trata de esto:
BOOL thisFunctionIsACFunction == (__PRETTY_FUNCTION__[0] != '-' && __PRETTY_FUNCTION__[0] != '+');
Está confiando en el comportamiento del compilador para anteponer un '-' o '+' para la instancia y métodos de la clase de objetos Objective-C. Cualquier otra cosa debe ser una función C (ya que las funciones C no pueden tener nombres que comiencen con '-' o '+').
Entiendo que este control es técnicamente un control en tiempo de ejecución, ya que __PRETTY_FUNCTION__
se reemplaza con char*
, y este es probablemente el principal obstáculo para mi solicitud de ayuda.
¿Cómo se te ocurrió con 'thisFunctionIsACFunction'? – Artelius
@Artelius editó la pregunta con más información –