2014-10-18 2 views
4

Когда я использую литералы массивов, я вижу странное поведение на разных компиляторах.Array literal синтаксис quirks

Первая проблема, я лицо, когда у меня есть программа, как это:

void f(int*) 
{ 
} 

int main() 
{ 
    using T = int[]; 
    f(T{1, 2, 3}); 
} 

На Clang 3.5 это компилируется нормально, но на g++ 4.9 он дает ошибку:

source_file.cpp: In function ‘int main()’: 
source_file.cpp:8:17: error: taking address of temporary array 
    f(T{1, 2, 3}); 

В VC++ он дает ошибку:

Process exit code is not 0: 255 

Так странно.

Если я T равно int[3] вместо int[], он будет компилироваться на VC++, но все еще дает ту же ошибку на г ++.

Кроме того, если изменить код:

using T = int[]; 
int* x = T{1, 2, 3}; 

затем лязг выдает ошибку, аналогичную г ++.

Какой компилятор прав?


Я понял, как заставить его работать на g++, сделав параметр f быть int (&&)[3], но в VC++ дает другую ошибку.

+0

Связанный: [Использование массива списка инициализации в качестве временного в C++ 11?] (https://stackoverflow.com/questions/15458883/using-array-init-list- as-tempor-in-c11) –

ответ

4

Clang is right. Построение объекта массива корректно формируется после [expr.type.conv]/3, и мы не берем адрес объекта массива (как говорит GCC), но пусть происходит разложение между массивами и указателями, что разрешено для массивы независимо от категории значения:

An lvalue or rvalue of type “array of N T” or “array of unknown bound of T” can be converted to a prvalue of type “pointer to T”. The result is a pointer to the first element of the array.

+0

@LightnessRacesinOrbit Строковые литералы - lvalues. – Columbo

+0

Ах, черт возьми. Как в сторону (потому что я признаю, что вы определенно правы в этом), знаете ли вы, где стандарт говорит так? 2.14.5/8 дает нам тип, но ... –

+0

5.1.1/1. Продолжать :) –

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