#ifndef max, непонятная ситуация, gcc
От: Sad Brother Россия  
Дата: 10.03.08 20:08
Оценка:
всем привет, возникла селдующая проблема. в кратце попытаюсь описать её суть. Есть большой продукт, с большим количеством написанного кода, написанного под win32. его надо перенести под unix. при компиляции одного из файлов в котором есть "примерно" следующее содержание

case p:
    c = max(a, b);


вылезла ошибка что-то типа "'max'undeclared (first use this function)"
первое, что странно, это то, что объявление макроса max было сделано в одном из базовых (def.h) заголовочных файлов:


// Define "max" if not already defined.
#ifndef max
#define max(a, b) (((a) > (b)) ? (a) : (b))
#endif


к сожалению, не могу полностью описать систему include-ов в исходном файле, так как это просто огромная паутина, судя по doxygen-у, но однозначно можно сказать, что директива #include "def.h" ни раз была бы включена в исходный файл при компиляции. кроме того, в одном из подключаемых заголовочных файлов, пройдясь вниз, по списку, опять же включеных заголовочных файлов, можно было натолкнуться на следующие объявление:

#include <algorithm>
using std::max;




самое загадочное, что проблема решилась следующим способом:

case p:
 #ifdef max
 c = max(a, b);
 #endif


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

Заранее спасибо!

p.s. в Visual Studio 2005 ошибок не возникает
Re: #ifndef max, непонятная ситуация, gcc
От: serg baburin Россия  
Дата: 10.03.08 21:08
Оценка:
Здравствуйте, Sad Brother, Вы писали:

SB>что полностью сбило меня с толку.... может кто-нибудь подсказать где зарыта собака в этом случае???

без исходников сложно сказать — вероятнее всего что-то типа:
#ifdef WINDOWS
    // Define "max" if not already defined.
    #ifndef max
    #define max(a, b) (((a) > (b)) ? (a) : (b))
    #endif
#endif

#ifdef LINUX
    // а здесь забыли
#endif


P.S. а не судьба было написать:
case p:
    c = std::max(a, b);
... << RSDN@Home 1.2.0 alpha rev. 790>>

Re: #ifndef max, непонятная ситуация, gcc
От: korzh.pavel Россия  
Дата: 10.03.08 21:09
Оценка: +1
Здравствуйте, Sad Brother, Вы писали:

SB>всем привет, возникла селдующая проблема. в кратце попытаюсь описать её суть. Есть большой продукт, с большим количеством написанного кода, написанного под win32. его надо перенести под unix. при компиляции одного из файлов в котором есть "примерно" следующее содержание


SB>
SB>case p:
SB>    c = max(a, b);
SB>


выглядит всё так как будто макрос max всё таки не определён. Хорошо бы посмотреть вывод препроцессора и посмотреть что происходит.

напиши так:
case p:
    c = (std::max)(a, b);


скобки вокруг имени функции нужны чтобы гарантированно вызвалась функция, а не макрос. Этим избежишь возможных конфликтов имён в будущем.
Re[2]: #ifndef max, непонятная ситуация, gcc
От: sergey_shandar США http://getboost.codeplex.com/
Дата: 11.03.08 00:27
Оценка:
Здравствуйте, serg baburin, Вы писали:

SB>Здравствуйте, Sad Brother, Вы писали:


SB>>что полностью сбило меня с толку.... может кто-нибудь подсказать где зарыта собака в этом случае???

SB>без исходников сложно сказать — вероятнее всего что-то типа:
SB>
SB>#ifdef WINDOWS
SB>    // Define "max" if not already defined.
SB>    #ifndef max
SB>    #define max(a, b) (((a) > (b)) ? (a) : (b))
SB>    #endif
SB>#endif

SB>#ifdef LINUX
SB>    // а здесь забыли
SB>#endif
SB>

SB>
SB>P.S. а не судьба было написать:
SB>
SB>case p:
SB>    c = std::max(a, b);
SB>


Согласен. А для того что бы исходники компилировались и на VC (после такой правки), добавить в опциях VC компилятора дефайн NOMINMAX.
getboost.codeplex.com
citylizard.codeplex.com
Re[2]: #ifndef max, непонятная ситуация, gcc
От: Sad Brother Россия  
Дата: 11.03.08 07:12
Оценка:
Здравствуйте, serg baburin, Вы писали:

SB>Здравствуйте, Sad Brother, Вы писали:


SB>>что полностью сбило меня с толку.... может кто-нибудь подсказать где зарыта собака в этом случае???

SB>без исходников сложно сказать — вероятнее всего что-то типа:
SB>
SB>#ifdef WINDOWS
SB>    // Define "max" if not already defined.
SB>    #ifndef max
SB>    #define max(a, b) (((a) > (b)) ? (a) : (b))
SB>    #endif
SB>#endif

SB>#ifdef LINUX
SB>    // а здесь забыли
SB>#endif
SB>

SB>
SB>P.S. а не судьба было написать:
SB>
SB>case p:
SB>    c = std::max(a, b);
SB>


никаких объявлений типа
#ifdef WINDOWS
#endif

#ifdef LINUX
#endif

нет
у меня возникло предположение, что может быть стандарнтный windows-кий макрос как-то перекрывает, использование моего макроса описанного в def.h...
сейчас хочу посмотреть о наличии подобных макросов под unix системами...
Re[2]: (function)(args...)
От: Roman Odaisky Украина  
Дата: 11.03.08 09:32
Оценка: 76 (4) :)
Здравствуйте, korzh.pavel, Вы писали:

KP>напиши так:

KP>c = (std::max)(a, b);
KP>скобки вокруг имени функции нужны чтобы гарантированно вызвалась функция, а не макрос. Этим избежишь возможных конфликтов имён в будущем.

+1, но что иметь в виду на будущее: вызов (function)(args) — с лишними скобками — отключает ADL (3.4.1/3, 3.4.2, 5.2.2).

#include <iostream>    // 1
                       // 2
int main()             // 3
{                      // 4
     endl (std::cout); // 5
    (endl)(std::cout); // 6
}                      // 7

adl.cpp:6: error: ‘endl’ was not declared in this scope


А вот ADL-friendly вариант:
#define foo(x) evil

void (foo)(X); // здесь или скобки, или так же, как ниже

#define MACROS_ARE_EVIL

foo MACROS_ARE_EVIL (arg);
До последнего не верил в пирамиду Лебедева.
Re[3]: #ifndef max, непонятная ситуация, gcc
От: sergey_shandar США http://getboost.codeplex.com/
Дата: 12.03.08 00:25
Оценка:
Здравствуйте, Sad Brother, Вы писали:

SB>у меня возникло предположение, что может быть стандарнтный windows-кий макрос как-то перекрывает, использование моего макроса описанного в def.h...


Советую убрать макрос max из def.h вообще и использовать std::max, если это С++.
getboost.codeplex.com
citylizard.codeplex.com
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.