2016-06-14 7 views
0

Если следующий код скомпилирован с gcc lfs.c -o lfs, он ничего не печатает. Однако, если он скомпилирован с g ++ lfs.c -o lfs, он печатает «_LARGEFILE_SOURCE, определяемый stdio.h!».Почему _LARGEFILE_SOURCE определен в stdio.h при компиляции с g ++, но не gcc?

#ifdef _LARGEFILE_SOURCE 
int largefile_defined_at_start = 1; 
#else 
int largefile_defined_at_start = 0; 
#endif 

// This defines _LARGEFILE_SOURCE, but only in C++! 
#include <stdio.h> 

int main(void) { 
#ifdef _LARGEFILE_SOURCE 
    if (!largefile_defined_at_start) 
    printf("_LARGEFILE_SOURCE defined by stdio.h!"); 
#endif 
    return 0; 
} 

В любом случае, _LARGEFILE_SOURCE не определяется компилятором:

gcc -dM -E - < /dev/null |grep _LARGEFILE_SOURCE |wc -l 
0 
g++ -dM -E - < /dev/null |grep _LARGEFILE_SOURCE |wc -l 
0 

Почему stdio.h определение _LARGEFILE_SOURCE когда GCC вызывается через внешний интерфейс г ++?

+0

На какой платформе вы программируете? Вы программируете против glibc? – fuz

+0

'_LARGEFILE_SOURCE' устарел в любом случае, почему, по-вашему, он вам нужен? Устаревший код? –

+0

@BaummitAugen Это не устарело. Если вы компилируете программу на i386 Linux, по умолчанию вы получаете 32-битный 'off_t'. '_LARGEFILE_SOURCE' является необходимым. – fuz

ответ

6

Потому что g ++ определяет _GNU_SOURCE, что в основном подразумевает все остальные макросы функций, такие как _LARGEFILE_SOURCE. Эти дополнительные макросы определяются, когда заголовок <features.h> включен, и большинство файлов заголовков системы включают <features.h> очень рано в файле. Тот факт, что _GNU_SOURCE предопределен, является постоянным источником разочарования для людей, которые хотят писать переносимый код на C++.

Я считаю, что вы можете просто:

#undef _GNU_SOURCE 

Однако, это нарушит libstdC++. Ой! Вот это боль! Все это связано с одним из самых больших недостатков дизайна на C++, что является фактом, что #include - это в основном текстовое включение. Поскольку большая часть libstdC++ определена (не просто объявлена!) В заголовочных файлах, это означает, что они загрязняют вашу программу _GNU_SOURCE.

Если вам необходимо получить доступ к интерфейсу спрятанного _GNU_SOURCE (например, strerror_r, например, который полностью разбит _GNU_SOURCE), то вы можете получить доступ к этим интерфейсам только из файлов, которые не используют никакой libstdC++ заголовков.

Это только проблема с libstdC++, насколько я знаю, поэтому я думаю, что вы также можете избежать проблемы с помощью libC++ или чего-то еще подобного.

+0

Это действительно странное дизайнерское решение. – fuz

+2

@FUZxxl: Я бы, вероятно, использовал слово «патологические», но «странные» работы. –

+0

Жестокий выбор! Я просто подтвердил, что это так, а затем принял ваш ответ. –