从外部函数访问外部结构属性
Access external struct attribute from outside function
我在玩一些外部变量,想知道为什么我不能从外部函数访问外部结构?
这是我的代码:
a.h
struct testing {
unsigned int val;
const char* str;
testing(unsigned int aVal, const char* aStr) : val(aVal), str(aStr){};
}
extern testing externalStruct;
a.c
#include "a.h"
testing externalStruct(10, "test");
test.c
#include <iostream>
#include "a.h"
unsigned int valCopy = externalStruct.val;
const char* strCopy = externalStruct.str;
int main()
{
std::cout<<"Direct val : "<<externalStruct.val<<std::endl; // Working, print 10
std::cout<<"Direct str : "<<externalStruct.str<<std::endl; // Working, print "test"
std::cout<<"Copy val : "<<valCopy<<std::endl; // Print 0 instead of 10
std::cout<<"Copy str : "<<strCopy<<std::endl; // Print nothing
return 0;
}
有什么想法吗?
未定义全局对象的初始化顺序。
在这种情况下,我猜 valCopy
和 strCopy
在 externalStruct
的构造函数被调用之前被初始化(=> 用 junk).
如果将 valCopy
和 strCopy
的初始化放入 main
主体中,我相信一切都会正常工作:
int main()
{
unsigned int valCopy = externalStruct.val;
const char* strCopy = externalStruct.str;
std::cout<<"Direct val : "<<externalStruct.val<<std::endl; // Working, print 10
std::cout<<"Direct str : "<<externalStruct.str<<std::endl; // Working, print "test"
std::cout<<"Copy val : "<<valCopy<<std::endl; // ??? did it work?
std::cout<<"Copy str : "<<strCopy<<std::endl; // ??? did it work?
return 0;
}
编辑
更多信息在这里“C++ global initialization order ignores dependencies?”
这个问题是由于静态(全局)变量的初始化顺序未知造成的。它甚至还有一个名字 static initialization order fiasco。这意味着来自 test.c 翻译单元的全局变量在来自 a.c 翻译单元的全局变量之前被初始化。
通常的解决方案是使用带有静态变量的函数。当函数被调用时,静态变量(在第一次使用时)被初始化。使用 c++11 初始化此类静态函数局部变量是线程安全的。
您的代码的解决方案如下所示:
a.h
//...
testing& GetExternalStruct();
a.c
//...
testing& GetExternalStruct() {
static testing externalStruct(10, "test");
return externalStruct;
}
test.c
unsigned int valCopy = GetExternalStruct().val;
const char* strCopy = GetExternalStruct().str;
您被 静态初始化顺序失败所欺骗 - C++ 的缺点之一。
两者都
unsigned int valCopy = externalStruct.val;
const char* strCopy = externalStruct.str;
和
testing externalStruct(10, "test");
在 main()
执行之前实际调用了 。不幸的是,C++ 没有允许您表达初始化应该以什么顺序进行的语言结构——这或多或少是由编译器随机决定的——在你的情况下,第一个块显然在第二个块之前执行,导致事实当您将值从那里复制到 valCopy
和 strCopy
.
时,externalStruct
尚未初始化
您可以通过 将初始化包装 到 return 静态初始化值的函数中来解决此语言缺陷 - 这使您可以控制这些初始化的完成顺序.
a.c:
testing &x() {
static testing *t = new testing(10, "test");
return *t;
}
test.c
...
valCopy = x().val;
strCopy = x().str;
...
我在玩一些外部变量,想知道为什么我不能从外部函数访问外部结构?
这是我的代码:
a.h
struct testing {
unsigned int val;
const char* str;
testing(unsigned int aVal, const char* aStr) : val(aVal), str(aStr){};
}
extern testing externalStruct;
a.c
#include "a.h"
testing externalStruct(10, "test");
test.c
#include <iostream>
#include "a.h"
unsigned int valCopy = externalStruct.val;
const char* strCopy = externalStruct.str;
int main()
{
std::cout<<"Direct val : "<<externalStruct.val<<std::endl; // Working, print 10
std::cout<<"Direct str : "<<externalStruct.str<<std::endl; // Working, print "test"
std::cout<<"Copy val : "<<valCopy<<std::endl; // Print 0 instead of 10
std::cout<<"Copy str : "<<strCopy<<std::endl; // Print nothing
return 0;
}
有什么想法吗?
未定义全局对象的初始化顺序。
在这种情况下,我猜 valCopy
和 strCopy
在 externalStruct
的构造函数被调用之前被初始化(=> 用 junk).
如果将 valCopy
和 strCopy
的初始化放入 main
主体中,我相信一切都会正常工作:
int main()
{
unsigned int valCopy = externalStruct.val;
const char* strCopy = externalStruct.str;
std::cout<<"Direct val : "<<externalStruct.val<<std::endl; // Working, print 10
std::cout<<"Direct str : "<<externalStruct.str<<std::endl; // Working, print "test"
std::cout<<"Copy val : "<<valCopy<<std::endl; // ??? did it work?
std::cout<<"Copy str : "<<strCopy<<std::endl; // ??? did it work?
return 0;
}
编辑
更多信息在这里“C++ global initialization order ignores dependencies?”
这个问题是由于静态(全局)变量的初始化顺序未知造成的。它甚至还有一个名字 static initialization order fiasco。这意味着来自 test.c 翻译单元的全局变量在来自 a.c 翻译单元的全局变量之前被初始化。
通常的解决方案是使用带有静态变量的函数。当函数被调用时,静态变量(在第一次使用时)被初始化。使用 c++11 初始化此类静态函数局部变量是线程安全的。
您的代码的解决方案如下所示:
a.h
//...
testing& GetExternalStruct();
a.c
//...
testing& GetExternalStruct() {
static testing externalStruct(10, "test");
return externalStruct;
}
test.c
unsigned int valCopy = GetExternalStruct().val;
const char* strCopy = GetExternalStruct().str;
您被 静态初始化顺序失败所欺骗 - C++ 的缺点之一。
两者都
unsigned int valCopy = externalStruct.val;
const char* strCopy = externalStruct.str;
和
testing externalStruct(10, "test");
在 。不幸的是,C++ 没有允许您表达初始化应该以什么顺序进行的语言结构——这或多或少是由编译器随机决定的——在你的情况下,第一个块显然在第二个块之前执行,导致事实当您将值从那里复制到 您可以通过 将初始化包装 到 return 静态初始化值的函数中来解决此语言缺陷 - 这使您可以控制这些初始化的完成顺序. a.c: test.cmain()
执行之前实际调用了 valCopy
和 strCopy
.externalStruct
尚未初始化
testing &x() {
static testing *t = new testing(10, "test");
return *t;
}
...
valCopy = x().val;
strCopy = x().str;
...