Здравствуйте, MT-Wizard, Вы писали:
MW>Недавно заметил, что вот такой код
MW>MW>std::cout << *new int(1, 2) << std::endl;
MW>
успешно компилируется в VC 2003, 2008, 2010 и выводит 2.
MW>Похоже, компилятор выбирает оператор "запятая" вместо списка инициализации.
MW>Нормальные компиляторы (gcc, comeau) выдают ошибку. Кстати, подсветка ошибок в VS 2010 тоже
MW>P.S.
MW>Выяснилось при использовании boost::make_shared<int>(1, 2) — компилится, как ни в чём не бывало.
Любимый стандарт:
5.3.4.15
A new-expression that creates an object of type T initializes that object as follows:
— If the new-initializer is omitted:
— If T is a (possibly cv-qualified) non-POD class type (or array thereof), the object is defaultinitialized
(8.5). If T is a const-qualified type, the underlying class type shall have a user-declared
default constructor.
— Otherwise, the object created has indeterminate value. If T is a const-qualified type, or a (possibly
cv-qualified) POD class type (or array thereof) containing (directly or indirectly) a member of
const-qualified type, the program is ill-formed;
— If the new-initializer is of the form (), the item is value-initialized (8.5);
— If the new-initializer is of the form (expression-list) and T is a class type, the appropriate constructor is
called, using expression-list as the arguments (8.5);
— If the new-initializer is of the form (expression-list) and T is an arithmetic, enumeration, pointer, or
pointer-to-member type and expression-list comprises exactly one expression, then the object is initialized
to the (possibly converted) value of the expression (8.5);
— Otherwise the new-expression is ill-formed.
8.5.12
The initialization that occurs in new expressions (5.3.4), static_cast expressions (5.2.9), functional
notation type conversions (5.2.3), and base and member initializers (12.6.2) is called direct-initialization
and is equivalent to the form
T x(a);
Разрешено передать ровно одно выражение в список между скобками new int(...).
Похожий код: Тут MSVC ругается на все.
int main()
{
int i(1,2); // так нельзя. Требуется одно выражение
}
struct s
{
int i;
s() : i(1, 2) // так нельзя тоже
{ }
}
int main()
{
}
Дополнение.
Скобки создают одно выражение, таким образом можно написать:
int main()
{
new int( (1, 2) );
int i ( (1, 2) );
int j = { 1 };
int h = { (1, 2) };
}
Здравствуйте, sidorov18, Вы писали:
S>Здравствуйте, _nn_, Вы писали:
__>>Скобки создают одно выражение, таким образом можно написать:
__>>__>>int main()
__>>{
__>> int i ( (1, 2) );
__>>}
__>>
S>А почему в выделенном случае i присваивается 2, а не 1?
Потому что возвращается самое правое выражение.
Недавно заметил, что вот такой код
std::cout << *new int(1, 2) << std::endl;
успешно компилируется в VC 2003, 2008, 2010 и выводит 2.
Похоже, компилятор выбирает оператор "запятая" вместо списка инициализации.
Нормальные компиляторы (gcc, comeau) выдают ошибку. Кстати, подсветка ошибок в VS 2010 тоже
P.S.
Выяснилось при использовании boost::make_shared<int>(1, 2) — компилится, как ни в чём не бывало.
Здравствуйте, _nn_, Вы писали:
__>Скобки создают одно выражение, таким образом можно написать:
__>__>int main()
__>{
__> int i ( (1, 2) );
__>}
__>
А почему в выделенном случае i присваивается 2, а не 1?