2015-12-22 2 views
12

Я только что узнал, что следующий код не является допустимым C++ (не разобрать на int после ~):Можно ли вызвать деструктор на int32_t?

int x = 5; 
x.~int(); 

Однако, следующий фрагмент кода делает работу:

int32_t x = 5; 
x.~int32_t(); 

Это связано с тем, что int32_t является typedef в моей конкретной реализации C++, и деструктор, по-видимому, может быть вызван любым типептическим типом.

Мой вопрос: является ли любая реализация C++ необходимой для компиляции второго файла? В частности, есть int32_t, гарантированный typedef, и является ли компилятор обязательным для уничтожения typedef, если он знает, что typedef typedefs что-то int?

+0

Да. 'int32_t' не является встроенным типом, и он не может быть макросом. –

+0

@ Cheersandhth.-Alf В стандартном проекте C++ 14 указывается тип typedef integer type int32_t; 'как определение' int32_t'. Насколько я могу судить, это не оставляет много места для пользовательских типов и всего или даже макроса. – Downvoter

+0

Чтобы избежать близкого вопроса/открытой войны вопроса, я не собираюсь голосовать, чтобы закрыть ее как дубликат, НО ... это дубликат связанного вопроса. Просто потому, что в этом другом вопросе не упоминается 'int32_t', это не означает, что этот другой вопрос не отвечает на ваши вопросы. –

ответ

8

Существует четкое требование, чтобы int32_t был типедом. Начнем с [cstdint.syn]/2:

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

Так оттуда мы рассмотрим требование для библиотеки C:

ЬурейеГо именем intN_t обозначает целочисленный тип с шириной N, не заполняющих бит, и представлением дополнительного кода.

[курсив добавлен]

Так что да, int32_t должен быть "ЬурейеЕ имя".

Хотя, насколько я знаю, это никогда не указывается в нормативном тексте, следующее примечание дает понять, что вызов деструктора для typedef, который разрешает встроенный тип, предназначен для компиляции и успешности ([класс .dtor]/16):

Примечание: обозначения для явного вызова деструктора могут использоваться для любого имени скалярного типа (5.2.4). Это позволяет писать код, не зная, существует ли деструктор для данного типа. Например,

typedef int I; 
I* p; 
p->I::~I(); 
+0

Фрагмент, конечно, неопределенное поведение (доступ члена через дикий указатель).Или Стандарт гарантирует, что использование этого синтаксиса в примитиве является no-op, и доступ к члену на самом деле никогда не происходит? –

+0

@BenVoigt: Хороший вопрос. Я не думаю, что указатель действительно должен быть разыменован, но я не уверен, что могу найти заявление, чтобы сказать это с уверенностью. –

+0

«Единственный эффект - это оценка постфиксного выражения перед точкой или стрелкой». (5.2.4) Итак, тогда '(* p) .I :: ~ I()' bad, но 'p-> I :: ~ I()' хорошо? И на самом деле не имеет значения, что такое тип? Похоже на недостаток. –

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

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