Какая разница в GCC между -std = gnu ++ 0x и -std = c ++ 0x и какую из них следует использовать? - PullRequest
27 голосов
/ 27 февраля 2011

У меня проблемы с <stdint.h> при использовании -std=c++0x в GCC 4.4.3 (для Android):

// using -std=c++0x
#include <stdint.h>
uint64_t value;  // error: 'uint64_t' does not name a type

Но использование -std=gnu++0x работает:

// using -std=gnu++0x
#include <stdint.h>
uint64_t value;  // OK

Является ли <stdint.h> несовместимым с C ++ 0x?

1 Ответ

20 голосов
/ 28 февраля 2011

Насколько я могу судить, я думаю, что это можно утверждать об ошибке реализации (или на самом деле, поскольку C ++ 0x не опубликован, не ошибка как таковая , а неполная реализациятекущее состояние будущего стандарта).

Вот почему, ссылаясь на n3225 для ожидаемого поведения -std=c++0x:

D.7 говорит

Каждый Cзаголовок, каждый из которых имеет имя формы name.h, ведет себя так, как будто каждое имя, помещенное в стандартное пространство имен библиотеки с помощью соответствующего заголовка cname, помещается в глобальную область пространства имен

OK, поэтомутак легко.Что <cstdint> помещает в стандартное пространство имен библиотеки?

18.4.1:

typedef unsigned integer type uint64_t; // optional

Как необязательно?18.4.1 / 2:

Заголовок определяет все функции, типы и макросы так же, как 7.18 в стандарте C

Drat.Что говорит стандарт С?Вынимая n1256, 7.18.1.1/3:

Эти типы являются дополнительными.Однако, если реализация предоставляет целочисленные типы с шириной 8, 16, 32 или 64 бита, без битов заполнения и (для типов со знаком), которые имеют представление дополнения до двух, она должна определить соответствующие имена typedef

Но держитесь, конечно, на Android с -std=c++0x GCC обеспечивает 64-битный тип без знака без битов заполнения: unsigned long long.Так что <cstdint> требуется для предоставления std::uint64_t и, следовательно, stdint.h требуется для предоставления uint64_t в глобальном пространстве имен.

Продолжайте, кто-то скажет мне, почему я неправ :-) Одна возможностьявляется то, что C ++ 0x ссылается на «ISO / IEC 9899: 1999 Языки программирования - C» без указания версии.Может ли быть так, что (a) 7.18.1.1/3 был добавлен в один из TC, а также (b) C ++ 0x намеревается ссылаться на оригинальный стандарт с 1999 года, а не на поправки с тех пор?Я сомневаюсь, что это так, но у меня нет под рукой оригинального C99, чтобы проверить (a), и я даже не уверен, как проверить (b).

Редактировать: о, какдля которого следует использовать -std=c++0x, на самом деле это еще не строгий режим, соответствующий стандартам, поскольку строгого стандарта еще нет.И даже если бы существовал стандарт, gcc 4.4.3 определенно не является его окончательной реализацией.Поэтому я не вижу большой необходимости использовать его, если -std=gnu++0x на самом деле более полно , по крайней мере, в этом отношении для вашей комбинации версии gcc и платформы.

Однако, gnu++0x включит другие расширения GNU, которые вы, возможно, не захотите использовать в своем коде.Если вы хотите написать переносимый C ++ 0x, то в конечном итоге вам захочется перейти на -std=c++0x.Но я не думаю, что GCC 4.4 или любая другая выполняемая реализация C ++ 0x еще достаточно завершена, чтобы было практично писать код из (чернового) стандарта, так что вы могли бы сказать с открытым лицом: «ЯЯ программирую на C ++ 0x, и это только 2011! ».Так что я бы сказал, используйте тот, который работает, и поймите, что какой бы вы ни использовали сейчас, вы, вероятно, в любом случае переключитесь на -std=c++11.

...