Почему невозможно инициализировать данные в глобальной области, передав их какой-либо функции? - PullRequest
0 голосов
/ 30 ноября 2010

Некоторое время я задавался вопросом, почему инициализация каких-либо данных путем передачи их какой-либо функции недопустима, несмотря на то, что конструкторы, которые в любом случае являются своего рода функцией, могут вызываться в глобальной области видимости, поэтому, если у нас есть что-то вродемассив в глобальной области видимости не может быть инициализирован какой-либо функцией, но если он находится в объекте структуры в глобальной области видимости, его можно инициализировать с помощью конструктора в области видимости:

//global scope

    char charArray[100];//can't be initialized using any function at global scope but in other scopes it could by being passed to some function

    struct Test{
     public:
      Test(){
       //initialization
      }
      char charArray[100];
    };
    Test obj();//now charArray can be initialized using constructor at global scope

Ответы [ 3 ]

5 голосов
/ 30 ноября 2010

На самом деле вы можете вызывать функции в глобальном масштабе.

int foo()
{
    return 5;
}

int bar = foo();

Это просто способ, которым C был разработан несколько лет назад, и вы не можете запускать функции самостоятельно в глобальном масштабе. Весь программный код начинается с main.

В общем, чем меньше вы зависите от глобальной инициализации (по возможности избегайте ее), тем меньше вам придется беспокоиться о странных ошибках статического запуска и таких проблемах, возникающих случайным образом.

Массивы - это другой случай, потому что вы никогда не можете присвоить результат вызова функции массиву - единственный способ инициализировать его в этом случае, как вы заметили, внутри конструктора.

РЕДАКТИРОВАТЬ: несколько злой подход к инициализации массива, вдохновленный комментарием:

bool do_init(int a[50])
{
    // Do whatever to init the array here.
    return true;
}

int array[50];
bool init_array = do_init(array);

Это работает только потому, что в модуле перевода порядок создания / инициализации глобалов гарантированно соответствует порядку их появления в файле.

2 голосов
/ 01 декабря 2010

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

Однако, вы можете «инициализировать» массив, если будете хранить эти два вместе.

#include <cstdio>
#include <cstring>

bool init(char* arr)
{
    strcpy(arr, "Hello");
    return true;
}

char arr[100];
bool dummy = init(arr);

int main()
{
    puts(arr);
}

И затем массив можно обернуть в объект.

#include <array>
#include <cstdio>

std::array<char, 100> init()
{
    std::array<char, 100> arr = {'H', 'e', 'l', 'l', 'o', '\0'};
    return arr;
}

std::array<char, 100> arr = init();

int main()
{
    puts(&*arr.begin());
}
0 голосов
/ 01 декабря 2010

В C и C ++ каждое глобальное значение должно иметь свой размер и тип, известные во время компиляции. Причина этого заключается в том, что они в конечном итоге размещаются в некотором разделе связанного двоичного файла. Если вам нужно что-то как глобальное, так и динамическое, вы должны объявить глобальный тип указателя или тип, содержащий указатель, затем выделить динамические данные на раннем этапе и обновить указатель.

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