C массив указателей на верхнем уровне без объявления размера - PullRequest
2 голосов
/ 17 ноября 2010

Этот код компилирует и производит вывод, как я и ожидал.

#include <stdio.h>

int* ar[];

int main(void) {    
    ar[0] = 97;
    ar[1] = 98;
    ar[2] = 99;

    printf("%i\n", ar[0]);
    printf("%i\n", ar[1]);
    printf("%i\n", ar[2]);
    printf("%i\n", ar[3]);

    return 0;
}

/* output
97
98
99
0
*/

У меня такое чувство, что я делаю это неправильно на многих уровнях.Есть ли здесь какие-либо побочные эффекты?

Более того, почему массив указателей работает как глобальная переменная, а если я объявлю это в main, gcc выдаст ошибку?

Ответы [ 4 ]

4 голосов
/ 17 ноября 2010

Как минимум пара проблем:

1) ar - это массив указателей - вы присваиваете ему целые числа (и печатаете элементы как целые).Я получаю предупреждения об этом как от GCC, так и от MSVC.

2) объявление ar является «неполным типом», так как не имеет указанного размера.MSVC отказывается от ссылки, говоря, что не может разрешить символ ar, чего я и ожидал.GCC делает ссылку, выдавая предупреждение:

warning: array 'ar' assumed to have one element

Я предпочитаю поведение MSVC в этом случае.

В случае GCC вы получаете доступ к данным для 3 или 4 элементов массива только с 1элемент реально существует, поэтому вы обращаетесь к памяти, которая не принадлежит объекту, что является неопределенным поведением.Это приведет к повреждению памяти, сбою или, по-видимому, работе - даже если программа некорректна (как в вашем тесте).

2 голосов
/ 17 ноября 2010

Два слова: неопределенное поведение.Если он находится в main, gcc может сказать, что ar не было предоставлено места, поскольку его область ограничена стекомКогда ar является глобальным, компилятор не может гарантировать, что для него никто не выделит место.В некоторых системах могут быть вредные последствия, а в других - нормально.Дело в том, что он не всегда будет делать то, что вы ожидаете, потому что он не определен.

0 голосов
/ 17 ноября 2010

Если вы объявите

int ar[4]

с тобой все было бы в порядке. В этом случае ar является глобальным и инициализируется 4 ноля. Вы устанавливаете значения в main, а затем переопределяете 0.

Но без измерения нет пути.

0 голосов
/ 17 ноября 2010

int * a [] - массив указателей.И это пустой массив, для которого вы не выделили никакого пространства.Поведение кода не определено. Gcc, вызывающий / не вызывающий ошибку, является наименьшим из ваших беспокойств.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...