четверг, 13 января 2011 г.

Назначенные инициализаторы

Есть такая замечательная штука, как Designated Initializers. Эта возможность описана в стандарте ISO C99.
const char *msg[] = {
[0] = "No message",
[1] = "Message 1",
[2] = "Message 2",
...
};

const struct foo f = {
.field1 = 10,
.field2 = 20,
...
};
Всегда сожалел о том, что такой возможности нету в C++. Ведь бывают и просто структуры, не все же конструкторы городить. А такая возможность здорово помогает обезопаситься от ошибок при инициализации. Инициализация в традиционном стиле далеко не так наглядна и превращается в сущий ад, если структура содержит больше трех элементов.
const struct foo f = { 10, 20, ... };
И вот значит совершенно случайно скопировал кусок кода из .c в .cpp...
const struct KernelModifyCustomIoBindParam bind_params = {
.first = first_port,
.last = last_port,
.access = RESOURCE_ACCESS_READ | RESOURCE_ACCESS_WRITE,
};
Скомпилировал без ошибок. И только потом сообразил, что это никак не должно было скомпилироваться. Что-то здесь не чисто.

Надо сказать, что я, с некоторых пор, для своего баловства использую clang. Clang рулит и я с интересом слежу за его развитием.

И вот значит такая оказия... Компилится при полном уровне варнингом, хоть ты тресни. Переключился на gcc:
Compile for localhost test/Custom.cpp...
Custom.cpp: In member function ‘void suiteCustom::testBindPortToCustom::test_method()’:
Custom.cpp:29: ошибка: expected primary-expression before ‘.’ token
Custom.cpp:30: ошибка: expected primary-expression before ‘.’ token
Custom.cpp:31: ошибка: expected primary-expression before ‘.’ token
make[1]: *** [/home/dron/MDF.Temp/test_Custom.o] Ошибка 1
make: *** [test] Ошибка 2
Как и следовало ожидать - результат положительный, то бишь не компилится.

Что это? несоответствие стандартам в clang? или просто они тоже считают эту фичу клевой и допустили ее использование в c++? Надо пообщаться с разработчиками.

PS: Если ваша программа компилируется без ошибок, обратитесь к разработчику компилятора, он исправит ошибки в нем.. :D

PPS: fixed in r123582 :) В этот раз правда моего имени не написали, так что я теперь аноним.

3 коммент.:

Анонимный комментирует...

Испортили хороший компилятор. Сударь, вы подлец.

А фича отличная, очень жаль, что в c++ такой инициализацией пренебрегают и не только не переносят улучшения из си, но и уже работающее ломают. Даже нещщасный std::pair = {foo, bar} выдаёт варнинг :(

Анонимный комментирует...

Фича и в правду удобная, но я бы не сказал, что написание конструктора является столь неблагородным делом. Цель то одна и таже :) Или может присутствие конструктора больше намекает на то, что это все же класс, а не структура? :)

Andrey Valyaev комментирует...

Классы классами, но структуры тоже никто не отменял.

Системный уровень тоже остался, glibc всякий. можно конечно написать свой враппер с конструктором, но как-то от лукавого это.

Инициализация структур значениями через запятую - это помоему жесткач... :) Но в с++ такого нету.