以下代码是合法前向引用的情况吗?如果是,为什么?
public class MyClass
{
private static int x = getValue();
private static int y = 5;
private static int getValue()
{
return y;
}
public static void main(String[] args)
{
System.out.println(x);
}
}
Run Code Online (Sandbox Code Playgroud) 编译/链接-nostdlib似乎可以防止静态初始化,即使我用.init/ .finisections 添加我自己的crti.s和crtn.s.
是否有解决方法使g ++生成插入的静态初始化代码.init或我可以手动调用?
这是我试过的:
g++ -o test.o -c -fno-use-cxa-atexit test.cc # has _start (entry point)
# that calls _init and _main
as -o crti.o crti.s # has _init in section .init
as -o crtn.o crtn.s
g++ -o test ./crti.o test.o -nodefaultlibs -nostartfiles ./crtn.o
Run Code Online (Sandbox Code Playgroud)
-nodefaultlibs 单独包括静态初始化代码和调用,但强制使用libc-_start/_init.
-nodefaultlibs -nostartfiles 允许我使用自己的_start/_init,但不包括代码或调用静态初始化.
我对这段代码有一些严重的问题,来自svg-android:
public class ParserHelper {
private static final Field STRING_CHARS;
static {
try {
STRING_CHARS = String.class.getDeclaredField("value"); //<-- exception here
STRING_CHARS.setAccessible(true);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private final char[] s;
private final int n;
private char current;
public int pos;
public ParserHelper(String str, int pos) {
try {
this.s = (char[]) STRING_CHARS.get(str);
} catch (Exception e) {
throw new RuntimeException(e);
}
this.pos = pos;
n = s.length;
current = s[pos];
}
Run Code Online (Sandbox Code Playgroud)
在STRING_CHARS …
我们有一个表我们想要静态初始化,但MSVC(2015.1及更早版本)也会生成动态初始化程序.
以下是演示此问题的简化代码:
#define idaapi __stdcall
#define MAXSTR 1024
typedef int error_t;
typedef unsigned char uchar;
struct psymbol_t
{
short what; /* -1 - is error, */
/* 0 - any symbol,don't skip it */
/* else lxtype_t */
short callNumber; /* Number in table of metasymbols */
/* -1 - no metasymbol */
/* Error code if what == -1 */
uchar nextNumber; /* Number in current table */
/* 0xFF - end */
uchar actNumber; /* Number …Run Code Online (Sandbox Code Playgroud) 我们在配置lambdaj以使用Joda Time时遇到问题.由于LocalDate是最终的类,Lambdaj需要初始化如下:( 参见bug 70)
public class LocalDateArgumentCreator implements FinalClassArgumentCreator<LocalDate> {
private final long MSECS_IN_DAY = 1000L * 60L * 60L * 24L;
public LocalDate createArgumentPlaceHolder(int seed) {
return new LocalDate((long)seed * MSECS_IN_DAY);
}
}
ArgumentsFactory.registerFinalClassArgumentCreator(LocalDate.class, new LocalDateArgumentCreator());
Run Code Online (Sandbox Code Playgroud)
由于我们需要在几乎所有地方应用此配置,因此我们缺乏如何实现此配置的选项.我们的应用程序是基于Spring和Wicket的Web应用程序.
我提出了三种不同的选择:
由于核心模块包含在每个其他模块中,因此所有模块都包含该类.剩下的问题是,即使没有对目标类的引用,静态块总是会被初始化吗?
例
public final class LambdajInitializer {
static {
// initialize like above
}
}
Run Code Online (Sandbox Code Playgroud)
applicationContext.xml缺点:从未对非Spring测试进行初始化
示例:在applicationContext-core.xml中(包含在每个模块中)
<bean class="...LambdajInitializer" />
public class LambdajInitializer {
@PostConstruct
public void init() {
// Lambdaj initialization
} …Run Code Online (Sandbox Code Playgroud) 保证在C++标准首次使用时实例化静态本地.但是,我想知道如果我在构建时访问静态本地对象会发生什么.我认为这是UB.但在以下情况下避免这种情况的最佳做法是什么?
Meyers Singleton模式在静态getInstance()方法中使用静态局部来在第一次使用时构造对象.现在,如果构造函数(直接或indireclty)getInstance()再次调用,我们将面临静态初始化尚未完成的情况.这是一个最小的例子,它说明了问题情况:
class StaticLocal {
private:
StaticLocal() {
// Indirectly calls getInstance()
parseConfig();
}
StaticLocal(const StaticLocal&) = delete;
StaticLocal &operator=(const StaticLocal &) = delete;
void parseConfig() {
int d = StaticLocal::getInstance()->getData();
}
int getData() {
return 1;
}
public:
static StaticLocal *getInstance() {
static StaticLocal inst_;
return &inst_;
}
void doIt() {};
};
int main()
{
StaticLocal::getInstance()->doIt();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在VS2010中,这没有问题,但VS2015死锁.
对于这种简单,减少的情况,显而易见的解决方案是直接呼叫getData(),而无需getInstance()再次呼叫.但是,在更复杂的情况下(根据我的实际情况),这种解决方案是不可行的.
如果我们改变getInstance()方法来处理像这样的静态局部指针(从而放弃Meyers Singleton模式):
static StaticLocal …Run Code Online (Sandbox Code Playgroud) 我想知道为什么C,C++和Java中的静态变量默认初零归零?为什么局部变量不是这样呢?
gcc 4.5.1,SuSE Linux i686
假设我们有以下代码:
template<typename realT> class B
{
public:
B() {std::cout << "B()" << std::endl;}
};
template<typename realT> class A
{
public:
static B<realT> static_var;
};
template<typename realT> B<realT> A<realT>::static_var;
template<> B<float> A<float>::static_var;
template<> B<double> A<double>::static_var;
int main()
{
A<float> test;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我们将不会在stdout中输出任何内容.编译器不会生成代码来初始化类A的float和double特化.
但是..如果我们要改变这样的初始化:
template<> B<float> A<float>::static_var = B<float>();
template<> B<double> A<double>::static_var = B<double>();
Run Code Online (Sandbox Code Playgroud)
编译器将生成这样的代码,我们将在输出中有两个"B()".
有人可以帮助我理解这种行为吗?
一个最近的问题吸引了我的注意,该方法constexpr在C++ 14已经改变.新功能是,如果其初始化程序由constexpr构造函数组成,即使变量的类型不是文字类型,也可以在静态初始化阶段初始化具有静态存储持续时间的非局部变量.更准确地说,[basic.start.init]中的新措辞是:
甲恒定初始化为一个对象
o是一个常量表达式,不同之处在于它还可以调用用于constexpr构造的表达o和它的子对象,即使这些对象是非文字类类型的[ 注意:这样的类可具有一个非平凡析构函数 - 结束语 ].恒定初始化执行[...]如果与静态或线程存储持续时间的目的是通过一个构造函数调用初始化,并且如果所述初始化全表达是一个常数初始化为对象[...]
典型的例子是std::unique_ptr,"手写"应该永远不会更糟糕:
std::unique_ptr<int> p; // statically initialized by [unique.ptr.single.ctor],
// requires no code excution
int main()
{
p = std::make_unique<int>(100);
}
// p is destroyed eventually
Run Code Online (Sandbox Code Playgroud)
在此添加之前,静态初始化变量是引用类型或文字对象类型,因此具有简单的析构函数.但是现在一个静态初始化的全局变量可以有一个非平凡的析构函数.
对于动态初始化的全局对象的析构函数,如何针对其他静态初始化的析构函数调用这样的析构函数调用,以及析构函数如何调用序列?
我经常使用以下习惯用法进行静态初始化:
def compute_answer() -> int:
if compute_answer.ret is None:
# Do stuff that only happens the first time
compute_answer.ret = 42
return compute_answer.ret
compute_answer.ret = None
Run Code Online (Sandbox Code Playgroud)
但是,使用 mypy 进行类型检查会出现以下错误:
compute.py:2: error: "Callable[[], int]" has no attribute "ret"
compute.py:4: error: "Callable[[], int]" has no attribute "ret"
compute.py:5: error: "Callable[[], int]" has no attribute "ret"
compute.py:7: error: "Callable[[], int]" has no attribute "ret"
Run Code Online (Sandbox Code Playgroud)
如何抑制这些错误,尤其是本地错误(例如,仅此函数/属性)?
python typechecking static-initialization mypy python-typing