开发者

Why initializing data at global scope by passing it to some function is not possible?

I've been wondering for a while why initializing any data开发者_JAVA技巧 by passing it to some function is not permitted despite the fact that constructors that are a kind of function anyway can be called at global scope, so if we have something like an array at global scope it can't be initialized by any function but if it was in an object of a structure at global scope then it could be initialized using a constructor at the scope:

//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


Actually you can call functions at global scope.

int foo()
{
    return 5;
}

int bar = foo();

It's just the way that C was designed years ago that you can't have functions run on their own at global scope. All program code starts at main.

In general, the less you depend on global initialization (avoid it if possible), the less you'll have to worry about weird static-init errors and such problems randomly cropping up.

Arrays are a different case because you can never assign the result of a function call to an array - the only way to initialize it in this case is inside a constructor as you observed.

EDIT: Somewhat evil approach to initialize an array inspired by a comment:

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

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

This only works since within a translation unit the order of creation/initialization of globals is guaranteed to be the order they appear in the file.


Arrays cannot be directly initialized with the result of a function call, because arrays can't be assigned.

However, you can "initialize" the array if you keep these two together.

#include <cstdio>
#include <cstring>

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

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

int main()
{
    puts(arr);
}

And then, an array can be wrapped into an object.

#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());
}


In C and C++, every global value must have its size and type known at compile time. The reason for this is that those end up allocated in some section of the linked binary. If you need something to be both global and dynamic, you should declare a global with a pointer type or a type containing a pointer, then allocate the dynamic data early on and update the pointer.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜