views:

203

answers:

2

Hi,

In C++98/C++03, there are no pure/const function keywords in the language.

  1. Has this changed in C++0x?

  2. If so, is it possible to set such a flag even on function objects (std::function)? So I can pass some function pointer or lambda functions and additional give the information that it is a pure/const function? The called function may have an optimized execution path for such a function.

  3. Is there some way to check if a given function is pure/const? I.e. for example, if there is such flag on std::function as described above, I probably could just check that flag. But maybe there is even a more general way.

If it has not changed, why not? I think it might be quite useful to have such a support.

Are there any open proposals about it?

+8  A: 
  1. Has this changed in C++0x?

No. There is a constexpr but it means compile time constant. If its parameters are constexprs too then it's executed at compile time, but it's a regular function otherwise. Since they must be defined in the same translation unit and consist of a single return statement they probably will be inlined and the above optimization will be performed. It can't be used to provide the compiler information about externally linked function.

If it has not changed, why not? I think it might be quite useful to have such a support.

Actually I don't think you need it. The language is already too big, and the programmer can easily rewrite this code to be more efficient based on her knowledge anyway. Unlike restrict it doesn't provide any info that can't be expressed by other means.

Are there any open proposals about it?

I haven't seen any committee papers on that topic.

ybungalobill
Thanks for the info. But pure/const really would provide more info that can in some cases be very complicated / mostly impossible to express otherwise. The compiler even could add memoization just transparently.
Albert
@Albert: Automatic memoization is unlikely to happen in C++. You could add it to your own functions, though. For example, building on `std::function<fn_type>`, it is probably possible to create `my_memoized_function<fn_type>`.
Potatoswatter
@Albert: but you could just implement memoization yourself, so once again, it's nothing that couldn't be expressed otherwise.
jalf
@Albert: btw, if the compiler actually has the definition of your function then it can easily see that it has no side effects and mark it "pure" automatically. I don't know of any compiler that does such optimization though. Note that "pure" doesn't introduce new semantics - it doesn't change the behavior of the program. The committee added a standardized attributes syntax that can be used for compiler features that don't effect the behavior. So we can expect compilers to implement restrict and pure through this syntax.
ybungalobill
@jalf: That is not the point about compiler optimisations. The point about compiler optimisations is if the compiler has any chance to do it himself. It is not possible at all to do this without knowing if the function is pure or const. (Whereby memoization might be a too extreme thing, I don't know if any compiler nowadays is doing this.)
Albert
@ybungalobill: That only works if the compiler has the definition. The point is to not put everything in header files but to be able to split your code in different cpp-files. Also, maybe you are using another library. For example, some libc implementations have also marked most of its functions (strlen, sin/cos, etc) as pure or const just because of this.
Albert
@Albert: that's what I said. That's why visual-studio moved to link time code generation a long time ago. I don't think that we need to introduce a new language extension just for any single optimization scenario. Think of `register` nowadays.
ybungalobill
@ybungalobill: I think you cannot do such optimisations at link time anymore. Also, there are still cases where you want to put such attribute but where the function is not pure/const in a strict sense.
Albert
@Albert: visual studio **does** cross compilation-unit inlining. So I don't see why you can't do this optimization too.
ybungalobill
@ybungalobill: Because it is much more than just inlining. It is rearranging the whole code of the function. And it must have analysed the other function (and all function it uses etc.) already before to know if it is pure/const. But I don't know at which stage the MS compiler is doing what. Afaik, the MS compiler does not know at all about such optimisations or has hardcoded some cases (like using `strlen` in a for-loop).
Albert
+1  A: 

gcc uses __attribute__(( <attr> )) to define extra attributes on functions.

  • pure: only accesses (but does not modify) parameters and global memory. GCC uses this information to determine if the optimizer can completely omit repeated calls to the function (local-memoization). Two notable pure functions are strlen and memcmp.

  • const: not to be confused with C++ const, const functions only accesses parameters and those parameters must not be pointers. It is basically a more restricted version of pure. The optimizer treats const functions that same as pure. Though in theory it could perform more aggressive (non-local) memoization than it does for pure.

C++0x's new attribute syntax (§7.6) was designed to do just this sort of thing. Currently you cannot use C++'s attribute syntax to set GCC attributes, but that may change in the future.

So you will be able to assign the pure attribute to functions using the attribute syntax. But there isn't a standard pure attribute. pure will be compiler specific, but it will do the right thing on gcc.

For the curious, here is the list of the standard attributes:

  • align
  • noreturn
  • override
  • hiding
  • base_check
  • carries_dependency
caspin