From: marc.glisse@gmail.com   
      
   Daniel Krügler wrote:   
      
   > On 2011-08-25 01:44, Marc wrote:   
   >> In C++, it is fairly common to pass functions an extra argument that   
   >> is used purely for dispatching purposes (or at least type   
   >> information), from a tag class that doesn't have any content. For   
   >> instance:   
   >> template void f(Iterator i){   
   >> f(i, std::iterator_traits::iterator_category());   
   >> }   
   >> followed by overloads:   
   >> template void f(Iterator i,std::input_iterator_tag){   
   >> /* ... */   
   >> }   
   >> template void f(Iterator i,std::forward_iterator_tag){   
   >> /* ... */   
   >> }   
   >> etc.   
   >>   
   >> In simple cases, everything is inlined and the use of the tag class is   
   >> indeed pure syntactic sugar. In other examples, it isn't always   
   >> inlined, and real function calls happen.   
   >>   
   >> Now in all ABIs I have seen, since sizeof(Tag)==1, an object of size 1   
   >> is copied, put on the stack (or in a register), etc, and nothing takes   
   >> advantage of the fact that it could be implemented as a function with   
   >> 1 fewer argument (if it is passed by reference, that can't be ignored   
   >> as someone might look at the address). Sadly being an empty class is   
   >> not enough, there should also not be any user-specified copy   
   >> constructor or the change becomes noticable.   
   >>   
   >> Would such an optimization be legal/possible? Does any compiler do it?   
   >> If not, is it just considered not worth the trouble? (I admit it   
   >> sounded more convincing before I thought of the copy constructor   
   >> issue)   
   >   
   > It should be possible unless you could observe the difference as   
   > described by the definition of observable behaviour in the standard.   
   > Since assembler output or any binary format is unspecified, the   
   > differences within such files does not belong to observable   
   > behaviour.   
   [...]   
   > I don't understand what your reference to the copy constructor is   
   > supposed to mean. If you have the funny idea that you could define a   
   > non-trivial copy-constructor for this empty type with observable   
   > side-effects, the compiler naturally cannot eliminate that in your   
   > example. But why should you do that?   
      
   I am talking about the ABI, which means the implementation, not the   
   language itself. In that sense it may be a bit OT, but it is not   
   specific to any implementation.   
      
   I don't particularly want to have a non-trivial copy constructor with   
   observable side-effects (actually, it is not any kind of side effect   
   that matters, printing stuff is fine, looking at the addresses of the   
   variables copied from and to is not).   
      
   I am trying to think of how compilers could implement the passing of   
   empty structs as arguments by copy. Currently, they implement it like   
   passing a char (in terms of putting stuff in registers, on the stack,   
   etc), which is fine but not optimal. It looks like it would make sense   
   to just not pass anything at all. The compiler has access to the body   
   of the class both when calling and defining the function so it can   
   detect emptiness. The compiler could reserve one byte (and usually   
   optimize that away as unused) inside the called function for the   
   "copied" empty object, in case something wants to take an address. And   
   nothing would notice the difference with the current "pass a char"   
   implementation... except possibly if there is a special copy   
   constructor. We could still run the code of the copy constructor,   
   either in the caller or the callee, but none has access to the   
   addresses of both the object copied from and the new object copied to,   
   so if the copy constructor uses those, the difference may be noticable   
   and thus it would be illegal. So it looks like it would be possible to   
   define an ABI that passes empty structs by value as size 1 objects if   
   there is a non-default copy constructor and as nothing otherwise.   
      
   Does it make more sense now?   
      
      
   --   
    [ See http://www.gotw.ca/resources/clcm.htm for info about ]   
    [ comp.lang.c++.moderated. First time posters: Do this! ]   
      
   --- SoupGate-Win32 v1.05   
    * Origin: you cannot sedate... all the things you hate (1:229/2)   
|