Корректно или нет?
интересуюсь плюсами довольно давно... вообщем преамбулу отбросим,
нашёл баг еще в начале года в VS2017 (15.6.х) компилере (пофиксили буквально неделю назад в обнове 15.7.1)
баг в том что если есть например родительский класс с парой мемберов(неважно сколько и каких) и конструктором принимающим допустим 2 аргумента, то если с дочернего класса из constructor member initializer попытаться вызвать этот конструктор юниформно и не с 2мя аргументами а например с тремя, то есть derived() : base{1,2,3}{} то студийный компилер это спокойно хавал (в отличии от gcc и clang, и даже родного IntelliSense,который это место считал ошибочным), и на выходе получалось что базовый класс не проинициализирован а в дочернем всё ок. но это ладно, пофиксили и хорошо, просто
тут еще одна фантазия возникла:
#pragma pack(1)
struct _jGate
{
// due to initializers, added implicit ctor and called on creation
const unsigned char j_code = 0xEE;
unsigned int j_address;
const unsigned short int j_segment = 0x0033;
};
#pragma pack()
...
jGate stub{ 1}; // sets j_code member to 1, which is initially const.! Clang & gcc does same
// stub.j_code = 0xee; // error C3892: 'stub': you cannot assign to a variable that is const
тут вот вопрос, а вообще логично ли инициализировать константный мембер если у него уже в определении структуры есть инициализатор? (это я вообще юниформной инициализаций заморочился)
(пс код и комменты писать по русски не могу - глаза режет)
Меня в последнее время вообще крайне бесит msvc количеством своих багов. Особенно в темплейтах. Как только начинаешь наворчивать что-нибудь чуть сложнее чем просто темплейтная коллекция, то сразу тут тебе и 'internal compiler error' с последующем крашем и 'optimizer crash' и просто ошибка компиляции, хотя его коллеги (gcc и clang) спокойно со всем этим делом справляются (вот например баг который я нашел у них https://stackoverflow.com/questions/50282217/parameter-pack-...).
Ладно, баги это одно.
А вот расширения которые майрософт придумали для компилятора вообще лютое зло. Потому что некоторый код становится крайне сложно использовать другим компилятором.
Ну например
class Vector3f
{
public:
union
{
float values[3];
float x, y, z;
};
};
void UseVector3f(Vector3f arg) {
arg.values[0] = 1.0f;
arg.x = 1.0f;
}
Вот такой вот анонимный юнион который выкидывает свои поля в класс в котором он объявлен будет работать только в msvc. Очень удобно. До тех пор пока это не нужно собрать другим компилятором (причин тому может быть много). Надо пройтись по всему коду и заменить x y и z на values[0], values[1], values[2] (или наоборот). А такие классы могут использоваться очень во многих местах.
На самом деле многие компиляторы поддерживают это, но это нужно включать отдельно.
Не знаю зачем все это написал, накипело прост