Подтвердить что ты не робот

Какая разница в GCC между -std = gnu ++ 0x и -std = С++ 0x и какой из них следует использовать?

У меня возникают проблемы с <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> несовместимым с С++ 0x?

4b9b3361

Ответ 1

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

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

D.7 говорит

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

Хорошо, пока что так просто. Что помещает <cstdint> в стандартное пространство имен библиотек?

18.4.1:

typedef unsigned integer type uint64_t; // optional

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

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

убирайся. Что говорит стандарт C? Вывод 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 в глобальном пространстве имен.

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

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

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