Click here to Skip to main content
15,887,683 members
Please Sign up or sign in to vote.
1.00/5 (4 votes)
Lets imagine such a code example:
C++
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);
  }
};

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 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:
C++
class MyStaticSingleton {

public:
  static const volatile MyStaticSignleton INSTANCE;
...

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?
Posted
Updated 8-Jun-16 6:26am
Comments
Philippe Mori 8-Jun-16 20:16pm    
Your code is too complicate for the question... Singletons and compile-time vs run-time are not related so why make harder to follow than necessary?
Philippe Mori 8-Jun-16 20:25pm    
The effect of volatile is somewhat compiler dependant.

If you really want to be sure that some code is executed at run time, then put that code in an external library...
Shvetsov Evgeniy 9-Jun-16 9:25am    
Thanks for your reply! Putting the code into an external library (you're talkig about the dynamic lib., of course) is the possible way, yes, thank you!

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
 
Share this answer
 
v4
Comments
Shvetsov Evgeniy 8-Jun-16 16:14pm    
1) volatile is NOT a recommendation, ofcourse not, never be, never was. I'l reccomend you familiarize yourself with this qualifier, as you currently clearly misundersttod it. Here is a good article: http://www.drdobbs.com/parallel/volatile-vs-volatile/212701484

2) There is, of course, dynamic singleton, which is, opposite to static, allocated and created on demand in run time.

3) My singleton realization is a simple "out of the box" solution, if you can proof you can properly create many instances of it, then show me how! :)
Sergey Alexandrovich Kryukov 8-Jun-16 17:03pm    
1) All right, thank you.
2) Load on call singleton is also static. You are talking about the lazy initialization. It does not make anything non-static.
3) I'm not trying to proof anything, thank you, I just want to help you. The right implementation is trivial. My point is different. I never said it does not behave as singleton, I just say it's a bad implementation, pretty much defeating the purpose. You could simply have a static instance of some class, with exact same success. Static instance should be private.

Anyway, I answered your question about compile time.

—SA
Shvetsov Evgeniy 8-Jun-16 17:38pm    
Thanks for your answer! Unfortunatly, it's not i was looking for, but anway still thank you!

1) This is lazy init, yes, there are plenty of ways how to implement singleton pattern (which is, in fact, applys the only restriction of one and single instance per any unit of execution time). The good example of how it can be done is shown in the wikipedia: https://en.wikipedia.org/wiki/Singleton_pattern#Example - there 5 (!) ways how to do that JAVA-way.

2) I understood what you're talking about, YES, we can set the instance private while proiding the public getter to access it, BUT there is just NO reson to do that when your singleton is a CONST. It's just meaningles in this case. Just minimalistic minimalistic way for implementation :)
Sergey Alexandrovich Kryukov 8-Jun-16 17:44pm    
You are very welcome. That's the thing; it's clear what you are looking for. The question, formally, is about compile-time elaboration; and most of the reset is unrelated to it. Yes, there are different ways to implement a singleton, it's pretty boring stuff and not really much relevant here.
—SA
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[^]
 
Share this answer
 
Comments
Shvetsov Evgeniy 8-Jun-16 15:19pm    
I'm sorry, but y're completly wrong here.

1) Here you can find an examples of how code runned compile time:

http://stackoverflow.com/questions/12108390/c11-compile-time-calculation-of-array
http://stackoverflow.com/questions/25890784/computing-length-of-a-c-string-at-compile-time-is-this-really-a-constexpr

2) The volatile keyword prevents optimization, as it tells the compiler to drop ANY assumptions which he maid among the volatile object, so free that object of optimizations.

"Basically, volatile announces that a value might change behind your program's back. That prevents compilers from caching the value (in a CPU register) and from optimizing away accesses to that value when they seem unnecessary from the POV of your program" - from http://stackoverflow.com/questions/3604569/what-kinds-of-optimizations-does-volatile-prevent-in-c

3) constexpr works diffrentley depending on what actually is marked "constexpr":

"constexpr function allows the function to be evaluated at compile time, but does not require that, so your answer is "maybe". It depends on the compiler's optimization settings. If you wish to have no runtime cost, you could force compile-time evaluation by assigning it to a constexpr variable" - from http://stackoverflow.com/questions/12785691/c-constexpr-at-compile-time?rq=1

Through we just completly reversed teacher/learner relationships here, stil thank you for your reply.
nv3 8-Jun-16 19:44pm    
Sorry, but code is never executed at compile time. That's why it's called "compile" time. But the compiler may evaluate expressions at compile time and thereby optimize performance. I guess that is what you mean by "code being executed at compile time". Yes, this is kind of running some calculations already at compile time vs. at run time. It's just not called "executing code", but "evaluating" expressions by the compiler.
Shvetsov Evgeniy 9-Jun-16 9:23am    
Thanks for your reply! Of course it is. Sorry, but this all is just meaningles, there are plenty of examples of such a things, calculating factroial in compile time, evaluating str. len. etc. There is just NO way to "evaluate" OR "calculate" something WITHOUT executing code.
nv3 9-Jun-16 11:55am    
When the compiler is evaluating a constant expression it is not your code that is being executed, but the compiler's. The compiler is just interpreting those parts of your source code that are constants and hence can be dealt with at compile time. YOUR code, i.e. the output of the compiler, is only being executed at run time -- well, that's why it's called run time, isn't it.

Anyhow, I don't want to disturb your view of the world. May you get happy with whatever view you have.
Shvetsov Evgeniy 9-Jun-16 13:24pm    
Of course the compiler is NOT executing MY code directly, because MY code is in the C++ language, which is human-readable, while the CPU executes the machine code AND this machine code is the result of MY human-readable C++ code being transfered by the compiler to the machine code, this is pretty obvious really :))

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900