如何确保代码在运行时执行,而不是编译时间? [英] How to ensure code to be executed at run time, NOT compile time?

查看:134
本文介绍了如何确保代码在运行时执行,而不是编译时间?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

让我们想象一下这样的代码示例:

Lets imagine such a code example:

class MyStaticSingleton {

public:
  static const MyStaticSignleton INSTANCE;
  
  ~MyStaticSignleton() = default;
  
  bool flag = predicate();
  
private:
  MyStaticSignleton() = default;
  MyStaticSignleton(const MyStaticSignleton&) = default;
  
  static bool predicate() throw() {
    const auto v1 = -1, v2 = 2;
    return static_cast<bool>(v1 + v2);
  }
};



如你所见:



1)那里是只有一个 c> MyStaticSingleton 类的实例, AND 它们都是 static AND 常数同时。



2) flag value,作为 static const cobject的子对象,实际上也是 static const



3) flag 在初始化期间,每个进程执行一次设置值阶段(作为静态对象的子对象) AND 然后从不更改。



4)谓词函数似乎在它的返回值中是非常可预测的,因为它运行的是编译时consts AND 所以返回编译时const ,这使得优化编译器重写为单行非常有吸引力:


As you can see:

1) there is only one instance of the MyStaticSingleton class is possible, AND it is both static AND constant simultaneously.

2) flag value, as a subobject of the static const cobject is, in fact, static const too.

3) flag value is setted once per process execution, during initialization phase (as a subobject of the static object) AND then never changed.

4) the predicate function seems to be very predictable in it's return value, as it operates of compile time consts AND so returns the compile time const, making it very attractive for the optimizing compiler to be rewrited to the one single line:

return true;



AND 然后ju st inline ,有效地删除了函数调用。



因为优化编译器倾向于摆脱 ANY 代码,他认为他可以在不改变程序的可观察行为的情况下抛出,我更好地认为在运行时没有任何事情,但只有一个 true 标志存在,这将是编译时const AND 甚至会在编译时分配 (在可执行文件中)。



多数民众赞成似乎没有问题,乍一看,那个不是真的。事实上, -1 AND 2 (这只是抽象的例子, NOT 将自己绑定到那个确切的在当前的hardawre平台上,可预测的编译时常量,可以在另一个(平台)上完全不同的值,使结果编译代码严格依赖于平台。



我尝试了什么:



所以我们需要运行运行时中的确切代码总是,显而易见的解决方案是标记te实例 volatile 否定这里的大多数优化:


AND then just inline, effectively removing the function call.

As the optimizing complier tends to get rid of ANY code, which he assumes he can throw out without changing the observable behaviour of a program, i'm condiser that there would be nothing done in the runtime, but just one single true flag exist, which will be compile time const AND would be even allocated during compile time (in the executable file).

Thats seems to be no problem here, at first sight, BUT that isn't true. In fact, that -1 AND 2 (this is just abstract examples, do NOT tie yourself to that exact values), while predictable compile time constants on the current hardawre platform, can be completely diffirent value on the other (platform), making so the result compiled code stricly platform-dependant.

What I have tried:

So we need to run the exact code in the run time always, the obvious solution is to mark te instance volatile denying here most-to-any optimizations:

class MyStaticSingleton {

public:
  static const volatile MyStaticSignleton INSTANCE;
...



我认为会解决问题 可能是我错了



可能还有其他解决方案,以确保在运行时执行某些代码, NOT 编译时间?



因为我们有 C ++ 11 constexpr 以确保编译时运行代码, NOT 运行时间,是否存在完全相反的情况?


I assume that would remove the problem OR may be i'm wrong?

May be there are also other solutions to ensure some code code would be executed at run time, NOT compile time?

As we have C++11 constexpr to ensure the code will be runned compile time, NOT run time, is there an exact reverse?

推荐答案

没有必要确保的情况。编译过程基于以下原则:没有编译时计算可能会影响执行的语义。这种计算的唯一目的是提高性能。



实际上,开发人员的目标恰恰相反:不要阻止编译器进行优化工作。特别是,如果某些信息可以静态知道,那么在编译期间可以预先计算一些常量值,最好不要阻止它。你总是可以将所有计算都转移到运行时,但这是一件坏事。



在整个代码示例中,我只能看到一个编译器可以执行的计算: code> v1 + v2 。在编译期间完成它是很好的。



也许你会混淆内联并进行编译时预先详细说明。不,内联也会在运行时执行。



您还应该了解 volatile inline 只是编译器的建议,实际的代码生成依赖于实现。您不应尝试使用此类关键字更改应用程序行为。对不起,我真的不明白你对静态,单例等的考虑。甚至名称MyStaticSignleton也令人困惑(好像有静态和非静态单例)。我觉得这一切都是基于一些我无法解释的误解。这些考虑因素与编译时详细说明的问题无关。也许这就是你需要了解的全部内容。



此外,你的代码不是一个合理的单例实现。成员 MyStaticSignleton.INSTANCE 以及它是静态的事实讲述了这个故事。与单个静态对象相比,单例的整个想法是将静态部分隐藏在类中。我没有提供关于单身设计的建议只是因为你没有问过它。您可以找到关于正确单件设计的大量教学材料。此外,避免这种设计模式通常是好的。可以编写没有单例的所有代码。请注意,在单个代码部分中共享单个对象与单个代码不同。



-SA
There are no situations when you have to ensure that. The compilation process is based on the principle that no compile-time calculations can possibly affect the semantics of the execution. The sole purpose of such calculation is improved performance.

In practice, the developer's goal should be just the opposite: not to prevent the compiler doing its optimization work. In particular, if some information can be known statically, so some constant values can be pre-calculated during compilation, it's good not to prevent it. You can always move all calculation into runtime, but it's a bad thing.

In your whole code sample, I can see only one calculation which a compiler can perform: v1 + v2. It's good that it's done during compilation.

Perhaps you are confusing inline with compile-time pre-elaboration. No, inline is also executed during runtime.

You also should understand that volatile and inline are only the "recommendations" for the compiler, the actual code generation is implementation-dependent. You should not try to change the application behavior using such keywords. Sorry, I did not really understand your considerations about static, singleton, and the like. Even the name "MyStaticSignleton" is confusing (as if there were static and non-static singletons). I feel that it all is based on some misconception I cannot explain. These considerations are irrelevant to the "problem" of compile-time elaboration. Maybe this is all you need to understand.

Also, you code is not a reasonable singleton implementation. The member MyStaticSignleton.INSTANCE and the fact it is static tells the tale. The whole idea of singleton, in contrast to just a static object, is hiding the static part in the class. I did not provide the advice on singleton design just because you did not ask it. You can find a lot of instructional material on correct singleton design. Besides, it's usually good to avoid this design pattern. It's possible to write all code without singletons. Note that having a single object shared in several parts of code is not the same as a singleton.

—SA


嗯......代码只在运行时执行 - 编译时间是从你可以读取的内容转换为机器可以理解的东西(或者至少是JIT编译器,如果适用的话)可以理解的。 br $>


volatile 关键字与此无关 - 它指定编译器无法优化输出和获取指令,因为它们可能随时被其他代码更改。 constexpr 只是告诉编译器在编译时可以 评估,就像2 * 2一样可能会,但复杂性更高: constexpr说明符(自C ++ 11以来) - cppreference.com [ ^ ]
Um...code is only executed at run time - compile time is when it's converted from something you can read to something the machine can understand (or at least, the JIT compiler if applicable) can understand.

The volatile keyword has nothing to do with that - it specifies that the compiler can't optimise out load and fetch instructions because they are liable to be changed by other code at any time. constexpr just tells the compiler that the value can be evaluated at compile time in the same way that "2 * 2" could be, but with a lot more complexity: constexpr specifier (since C++11) - cppreference.com[^]


这篇关于如何确保代码在运行时执行,而不是编译时间?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆