2015-04-30 5 views
2

Работа в новой для меня базовый код, и я наткнулся на какой-C код, который выглядит следующим образом:Когда я использовал /define для определения статической функции в работе C?

static int* functionA(int* anInt); 
#define functionA(anInt) (<a 1 line '? :' function>) 

Может быть, это очевидно для людей, которые по кодированию C является немного более свежим в их голове, чем у меня, но для меня это немного странно. Компилятор, похоже, согласен, как он выплевывает сообщение о

error: ‘functionA’ declared ‘static’ but never defined.

(я использую GCC 4.8.2.)

Как это получилось в какой-нибудь библиотеки кода, который мы оцениваем я полагаю, что для некоторых компиляторов некоторое время это действительно. Пожалуйста, кто-нибудь может объяснить, когда это действительно так?

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

+0

Параметр '# define' вещь является определение макроса препроцессор, а не определение функции. Затем предварительный процессор заменит все экземпляры 'functionA' (все экземпляры, найденные после определения макроса) на« тело »макроса. Определение функции будет, например, 'static int * functionA (int * anInt) {...}' –

+0

https://ideone.com/hDFhbJ показывает, что gcc не имеет проблем с компиляцией кода с неопределенной функцией, которая была объявлена ​​ранее. У вас должен быть экземпляр, где 'functionA' * is * вызывается через какой-то механизм или что-то еще. Предоставьте минимальный полный пример ... –

+0

Далее в том же файле .c есть: int * aValue = functionA (aVariable); Хотя я не понимаю, почему этого не может быть: int * aValue = (); предоставляется макросом. – TafT

ответ

2

As this is has turned up in some library code that we are evaluating I assume that for some compilers, some of the time, this is valid. Please could someone help explain when it is valid?

Если нет фактической определение функции А в исходный файл, в котором он объявлен, также не используется, компилятор должен выдать «объявленный» статический «но никогда не определенный» как предупреждение .

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

https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html

+1

Я использую этот параметр. Это объясняет, почему это выходит как ошибка и, возможно, авторы кода библиотеки оставили это как есть. – TafT

+0

Хорошо, тогда ответы «когда это было действительно» :) – traveh

+1

Вы технически верны. Если параметр -Werror не используется, это не будет ошибкой. Это так же справедливо, как и этот код, когда-либо похожим на звук вещей. – TafT

0

#define не определяет функцию, он заменяет видимые вызовы функций в коде с помощью встроенного выражения. (Выражение плохо сформировано, хотя, если я не пропущу что-то, возможно, это только местозаполнитель?) Единственный раз, когда фактический компилятор видит functionA в статическом объявлении; он жалуется, что функция никогда не определяется.

Ошибка компилятора для меня неожиданна - я бы предположил, что статическое объявление игнорируется, если функция никогда не вызывается. (Он никогда не вызывается, потому что #define приводит к замене этих «звонков».) Должно быть просто #define статическая декларация с использованием конструкции #if/#else, если действует «inlining by #define».

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

+0

Похоже, что использование только «fucntionA» в базе кода позже в том же файле .c. Он используется только обычным способом, но не предпринимается попытка взять адрес функции. – TafT

2

Ваш компилятор правильно, вы объявляли static функцию

static int* functionA(int* anInt); 

но нет никакого определения для этого, то вы добавили макрос, который будет заменять каждое вхождение functionA(value); в коде с (<a 1 line '? :' function>), следовательно, вы не может использовать функцию static, даже если у нее есть определение.

Определение функции будет

static int *functionA(int* anInt) 
{ 
    /* do something with `aInt' */ 
} 

при использовании макроса, препроцессор будет принимать этот код

#define addnumbers(x, y) ((x) + (y)) 

double x = addnumbers(1.5, 6.7); 

с

double x = ((1.5) + (6.7)); 
+0

Значит, вы говорите, что код в этой библиотеке никогда не будет скомпилирован? – TafT

+0

Нет, я не сказал, что это скомпилируется, потому что вы никогда не используете функцию 'static', так что на этапе связывания нет необходимости в ней. –

+0

Ну, это значит, что gcc выдает ошибку, если другие компиляторы не будут? –

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

  • Нет связанных вопросов^_^