статические массивы определяются с неуказанным размером, пустыми скобками?

Поскольку C++ кодирует фрагмент ниже:

class Foo {
    int a[]; // no error
};

int a[];     // error: storage size of 'a' isn't known

void bar() {
    int a[]; // error: storage size of 'a' isn't known
}

почему членская переменная не вызывает ошибку также? и каково значение этой членской переменной?

Я использую gcc версию 3.4.5 (особенная mingw-перспектива) через CodeBlocks 8.02.

На Visual Studio Express 2008 - Microsoft(R) C/C ++ Optimizing Compiler 15.00.30729.01 для 80x86, я получил следующие сообщения:

class Foo {
    int a[]; // warning C4200: nonstandard extension used : zero-sized array in struct/union - Cannot generate copy-ctor or copy-assignment operator when UDT contains a zero-sized array
};

int a[];

void bar() {
    int a[]; // error C2133: 'a' : unknown size
}

Теперь, этому нужен некоторый explaination также.

9
задан tshepang 27 February 2014 в 08:34
поделиться

4 ответа

C99 поддерживает так называемый «гибкий» член массива, которому разрешено быть последним членом структуры. Когда вы динамически выделяете такую ​​структуру, вы можете увеличить количество, запрошенное из malloc () , чтобы выделить память для массива.

Некоторые компиляторы добавляют это как расширение к C90 и / или C ++.

Таким образом, у вас может быть следующий код:

struct foo_t {
    int x;
    char buf[];
};


void use_foo(size_t bufSize)
{
    struct foo_t* p = malloc( sizeof( struct foo_t) + bufSize);

    int i;

    for (i = 0; i < bufSize; ++i) {
        p->buf[i] = i;
    }
}

Невозможно определить структуру с гибким членом массива напрямую (как локальную или глобальную / статическую переменную), поскольку компилятор не знает, сколько памяти нужно выделить на это.

Честно говоря, я не уверен, как можно легко использовать такую ​​вещь с оператором C ++ new - я думаю, вам придется выделить память для объекта с помощью malloc () и используйте размещение новое . Может быть, можно использовать некоторую перегрузку оператора new , специфичную для класса / структуры ...

8
ответ дан 4 December 2019 в 09:36
поделиться

Мы использовали это для обозначения какой-то записи переменной длины. Что-то вроде файла заголовка, в котором есть информация о том, сколько структур следует придерживаться, за которыми следуют сами данные. Это массив переменной длины, и я обнаружил, что он плохо поддерживается компиляторами. Некоторым нужен array []; а некоторые хотят array [0]; (Старый стиль).

0
ответ дан 4 December 2019 в 09:36
поделиться
class Foo {
    int a[]; // OK in C, invalid in C++. Does not work with inheritance.
}; // Idea is that structure is "extended" indefinitely by an array.
   // May work on your compiler as an extra feature.

int a[];     // error in C and C++: storage size of 'a' isn't known

void bar() {
    int a[]; // error in C and C++: storage size of 'a' isn't known
}

extern int a[]; // OK: storage size may be declared later.

int a[5]; // declaration of size before use.

Тип массива неопределенного размера является неполным. 8.3.4 / 1:

Если константное выражение опущено, тип идентификатора D - это «массив списка производных-деклараторов с неизвестной границей T», то есть неполный тип объекта.

Он должен быть завершен, чтобы участвовать в определении, то есть определение a должно содержать спецификацию размера или инициализацию с массивом указанного размера.

2
ответ дан 4 December 2019 в 09:36
поделиться

Язык C ++ позволяет опускать размер массива только в не определяющих объявлениях

extern int a[]; // non-defining declaration - OK in C++

int a[]; // definition - ERROR in C++

int a[5]; // definition - OK, size specified explicitly
int a[] = { 1, 2, 3 }; // definition - OK, size specified implicitly

Для указания размера массива всегда требуется декарация нестатических членов класса

struct S {
  int a[]; // ERROR in C++
};

, в то время как статический член класса декарации может опускать размер

struct S {
  static int a[]; // OK in C++
};

(определение того же члена, конечно, должно указывать размер).

Любые отклонения от этого поведения могут быть объяснены только расширенным нестандартным поведением вашего компилятора. Возможно, вам стоит указать некоторые дополнительные настройки компилятора, чтобы он вел себя более педантично.

12
ответ дан 4 December 2019 в 09:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: