在不同的访问器中指定静态局部变量的构造/销毁顺序 [英] Specify construction/destruction order of static locals in different accessors
问题描述
我遇到了 cxa_finalize
运行程序崩溃(这是一个程序,而不是其中的库):
$ ./ac-test.exe
断言失败:AcLock.cpp(54):AcLock
libc ++ abi.dylib:terminate called没有活动异常
中止陷阱:6
断言/崩溃是由于交互在对象和记录器之间。记录器在对象之前被销毁,但对象使用记录器。因此,弹出assert或crash的互斥量已经被销毁(因此,锁定日志记录时 pthread_mutex_lock
失败的原因)。
我阅读了指定变量的属性的GCC手册
a>和声明函数的属性,但我显然缺少某些内容。我将对象和记录器放置在访问器中的公共头中,并尝试指定构造顺序:
// AcGlobals.h
static AcLogger& GetLogger(){
static AcLogger logger __attribute __(init_priority(50));
return logger;
}
static AcSocketList& getAcceptSockets(){
static AcSocketList sockets __attribute __(init_priority(100));
return sockets;
}
这导致了一堆错误:
./ AcGlobals.h:24:46:error:expected';'在声明结束
static AcLogger logger __attribute __((init_priori ...
./AcGlobals.h:24:47:warning:声明不声明任何内容
[-Wmissing-declarations]
static Aclogger logger __attribute __((init_priori ...
我也试过将属性放在函数上,而不是变量:
// AcGlobals.h
static AcLogger& GetLogger()__attribute __(init_priority(50)){
static AcLogger logger ;
return logger;
}
static AcSocketList& GetAcceptSockets()__attribute __(init_priority(100)){
static AcSocketList socket;
return sockets;
}
这导致更多的问题:
./ AcGlobals.h:22:53:warning:GCC不允许在此
中的init_priority属性在函数定义[-Wgcc-compat] b $ b static AcLogger& GetLogger()__attribute __((init_priority(50))){
^
./AcGlobals.h:22:53:错误:只能使用文件范围的'init_priority'属性
定义对象类型
我也尝试了 __ attribute __((constructor(50) ))
而不是 init_priority
。
em:我在一台苹果机上工作。苹果有一个特征,其中构造函数优先级只适用于同一文件中的装饰函数和变量。
如何精确地指定构建和销毁本地静态对象的顺序?
解决方案这是一个经典的问题,当使用Meyers单例
(这基本上是你在做什么)。解决方案是
不是破坏单例;而不是静态局部
变量,您应该使用动态分配而不删除:
static AcLogger& GetLogger()
{
static AcLogger * logger = new AcLogger;
return * logger;
}
请注意,在这种情况下,您必须确保每次使用
记录器刷新(但这通常是这种情况);
否则,您可能会遇到未刷新的数据。
关于您尝试使用
编译器的扩展功能:不太熟悉它,但我不明白你如何
可以使用在局部变量 init_priority
的东西。
局部静态
变量的构造(和销毁)时间由语言定义(在这种情况下,
销毁时间不是你想要的) 。如果你想使用
这个非标准扩展,你可能必须使
实例变量成为一个静态类成员,或者甚至一个全局
(在这种情况下,你可以't使构造函数私有)。
I'm experiencing a crash in cxa_finalize
running a program (this is a program, and not a library within):
$ ./ac-test.exe
Assertion failed: AcLock.cpp(54): AcLock
libc++abi.dylib: terminate called without an active exception
Abort trap: 6
The assertion/crash is due to the interaction between an object and a logger. The logger is destructed before the object, but the object uses the logger. So the mutex being acquired that pops the assert or crash has already been destroyed (hence the reason pthread_mutex_lock
fails when locking the logger).
I've read the GCC manual on Specifying Attributes of Variables and Declaring Attributes of Functions, but I'm obviously missing something.
I placed the object and logger in a common header within accessors and tried to specify a construction order:
// AcGlobals.h
static AcLogger& GetLogger() {
static AcLogger logger __attribute__(init_priority(50));
return logger;
}
static AcSocketList& GetAcceptSockets() {
static AcSocketList sockets __attribute__(init_priority(100));
return sockets;
}
That resulted in a bunch of errors:
./AcGlobals.h:24:46: error: expected ';' at end of declaration
static AcLogger logger __attribute__((init_priori...
./AcGlobals.h:24:47: warning: declaration does not declare anything
[-Wmissing-declarations]
static AcLogger logger __attribute__((init_priori...
I also tried placing the attribute on the function rather than the variable:
// AcGlobals.h
static AcLogger& GetLogger() __attribute__(init_priority(50)) {
static AcLogger logger;
return logger;
}
static AcSocketList& GetAcceptSockets() __attribute__(init_priority(100)) {
static AcSocketList sockets;
return sockets;
}
This resulted in more problems:
./AcGlobals.h:22:53: warning: GCC does not allow init_priority attribute in this
position on a function definition [-Wgcc-compat]
static AcLogger& GetLogger() __attribute__((init_priority(50))) {
^
./AcGlobals.h:22:53: error: can only use 'init_priority' attribute on file-scope
definitions of objects of class type
I also tried __attribute__((constructor(50)))
instead of init_priority
with no joy.
Note: I'm working on an Apple machine. Apple has a 'feature' where constructor priority only applies to adorned functions and variables within the same file. So these cannot be spread out across translation units.
How, precisely, do I specify the order of construction and destruction of local static objects?
解决方案 This is a classical problem when using the Meyers singleton
(which is basically what you're doing). The solution is to
not destruct the singleton; instead of a static local
variable, you should use dynamic allocation without a delete:
static AcLogger& GetLogger()
{
static AcLogger* logger = new AcLogger;
return *logger;
}
Note that in this case, you will have to ensure that each use of
the logger flushes (but this is usually the case anyway);
otherwise, you may end up with unflushed data.
With regards to your attempt to use an extended feature of your
compiler: I'm not too familiar with it, but I don't see how you
can use something called init_priority
on a local variable.
The construction (and destruction) time of local static
variables is defined by the language (and in this case, the
destruction time is not what you want). If you want to use
this non-standard extension, you'll probably have to make the
instance variable a static class member, or maybe even a global
(in which case, you can't make the constructor private).
这篇关于在不同的访问器中指定静态局部变量的构造/销毁顺序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!