Почему обозначенные инициализаторы не реализованы в g++

Есть ли какая-то конкретная причина, почему поддержка назначенных инициализаторов не была добавлена ​​в g++? Является ли причиной того, что стандарты C99 пришли с опозданием, а g ++ был разработан ранее, и позже люди не заботились об этой проблеме, или есть некоторая внутренняя сложность в реализации назначенных инициализаторов в грамматике C++?

6 ответов

Решение

Как я отметил в комментарии, G++ не поддерживает стандартные инициализаторы C99, но поддерживает расширение GNU до C90, которое позволяет назначенным инициализаторам. Так что это не работает:

union value_t {
    char * v_cp;
    float v_f;
};
union value_t my_val = { .v_f = 3.5f };

Но это делает:

union value_t my_val = { v_f: 3.5f };

Кажется, это плохое взаимодействие между комитетами по стандартам C и C++ (нет особой причины, почему C++ не поддерживает синтаксис C99, они просто не учли его) и политикой GCC (C++ не должен ' t поддерживает синтаксис C99 только потому, что он находится в C99, но он должен поддерживать синтаксис расширения GNU, который обеспечивает точно такую ​​же вещь, потому что это расширение GNU, которое может применяться к любому языку).

Я столкнулся с этой же проблемой сегодня. g++ с -std= C++11 и C++14 действительно поддерживает назначенные инициализаторы, но вы все равно можете получить ошибку компиляции "test.cxx:78:9: извините, не реализовано: нетривиальные назначенные инициализаторы не поддерживаются", если вы не инициализируйте структуру в том порядке, в котором были определены ее члены. В качестве примера

struct x
{
    int a;
    int b;
};

// This is correct
struct x x_1 = {.a = 1, .b = 2};
// This will fail to compile with error non-trivial designated initializer
struct x x_2 = {.b = 1, .a = 2};

C++ не поддерживает это. Кажется, он даже не будет соответствовать стандартам C++0x: http://groups.google.com/group/comp.std.c++/browse_thread/thread/8b7331b0879045ad?pli=1

Кроме того, почему вы пытаетесь скомпилировать ядро ​​Linux с помощью G++?

По крайней мере, для g++-4.8 теперь это поддерживается по умолчанию.

А как насчет анонимных союзов?

В CI может быть это:

struct vardir_entry {
    const uint16_t id;
    const uint8_t sub;
    const char *name;
    const uint8_t type;

    const union {   
        struct vardir_lookup lookup;
        struct vardir_min_max_conf minmax;       
    };

    const union {
        const struct vardir_value_target_const const_value;
        const struct vardir_value_target value;
    };
};

И инициализируется так:

static const struct vardir_entry _directory[]{
        { .id = 0xefef, .sub = 0, .name = "test", .type = VAR_UINT32, .minmax = { .min = 0, .max = 1000 }, .value = VARDIR_ENTRY_VALUE(struct obj, &obj, member) }
    };

Однако в g++ даже с C++14 это приводит к той же "извините, не реализованной" ошибке. Нам нужно иметь возможность определять переменные C в C++, когда мы по крайней мере хотим модульно протестировать код C с помощью инфраструктуры тестирования C++. Тот факт, что такая ценная функция от C не поддерживается, - это позор.

Согласно http://gcc.gnu.org/c99status.html назначенным инициализаторам уже реализовано.

Какую версию g++ вы используете? (Попробуйте g++ - версию)

Другие вопросы по тегам