|
Prev: template args
Next: std::map performance
From: Olivier Langlois on 4 Apr 2008 04:25 Those functions are the default constructor, the copy constructor and the assignement operator. In the standard document (section 12), it is written that these functions are implicitly declared, and implicitly defined *if* they are used. Since they are defined on a usage basis, I am guessing that they have internal linkage and that there could be many occurances of these functions if they are used in more than 1 translation unit. Is this correct? If it is, would that be correct to say that if you want to make a program smaller, you should explicitly declare and define those functions even if they are identical than those that the compiler would generate to give them external linkage and to avoid multiple copies? Also, the standard categorize these functions as trivial or non- trivial based on some conditions but I have not found what was the consequences for a function being tagged one way or the other. Is anyone can explain? Greetings, Olivier Langlois http://www.olivierlanglois.net http://blog.olivierlanglois.net -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Daniel Krügler on 5 Apr 2008 04:28 On 4 Apr., 21:25, Olivier Langlois <olangl...(a)sympatico.ca> wrote: > Those functions are the default constructor, the copy constructor and > the assignement operator. > > In the standard document (section 12), it is written that these > functions are implicitly declared, and implicitly defined *if* they > are used. Since they are defined on a usage basis, I am guessing that > they have internal linkage and that there could be many occurances of > these functions if they are used in more than 1 translation unit. Is > this correct? Any discussion about linkage of constructors is irrelevant, because these entities have no associated linkage. Linkage requires the existence of a name: [basic.link]/2: "A name is said to have linkage when it might denote the same object, reference, function, type, template, namespace or value as a name introduced by a declaration in another scope" Constructors do not have names, [class.ctor]/1: "Constructors do not have names.[..] Constructors are also not addressable, [class.ctor]/12: "[..] The address of a constructor shall not be taken." The concept of linkage is not related to the fact whether something is implicitly declared or defined, used or not. One general rule is, [basic.link]/5: "In addition, a member function, static data member, class or enumeration of class scope has external linkage if the name of the class has external linkage." and thus can be applied to the copy assignment operator and it is also possible to get the address from such beast: [special]/1 "[..] a program may explicitly call, take the address of or form a pointer to member to an implicitly declared special member function". So, in fact your assumptions are not valid. > If it is, would that be correct to say that if you want to make a > program smaller, you should explicitly declare and define those > functions even if they are identical than those that the compiler > would generate to give them external linkage and to avoid multiple > copies? This relation does not exist, so it is mood. Explicitly writing a c'tor as a *non-inline* function can reduce multiple definitions. But the concepts of inline and linkage are independent. > Also, the standard categorize these functions as trivial or non- > trivial based on some conditions but I have not found what was the > consequences for a function being tagged one way or the other. Is > anyone can explain? Class types which are trivial also have trivial special member functions and thus provide special guarantees. E.g. they cannot have virtual functions, they have special layout guarantees N2588, [intro.object]/5: "[..] An object of trivial or standard-layout type (3.9) shall occupy contiguous bytes of storage.[..]" Calling a trivial destructor can be omitted, several conversions regarding pointers and references are allowed, which are not so for non-trivial classes. In current Standard C++ only types with trivial c'tors and copy assignment op's can be members of unions (This will probably be lifted for C++0x). Trivial c'tors can be omitted to be called for temporaries ([class.temporary]/3). HTH & Greetings from Bremen, Daniel Kr�gler -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Bart van Ingen Schenau on 5 Apr 2008 04:33 Olivier Langlois wrote: > Those functions are the default constructor, the copy constructor and > the assignement operator. > > In the standard document (section 12), it is written that these > functions are implicitly declared, and implicitly defined *if* they > are used. Since they are defined on a usage basis, I am guessing that > they have internal linkage and that there could be many occurances of > these functions if they are used in more than 1 translation unit. Is > this correct? No. The implicitly declared members are inline functions. This means that they have external linkage but multiple definitions may occur across different TUs. The linker is required to merge the different definitions that it encounters for inline functions. <snip> > Also, the standard categorize these functions as trivial or non- > trivial based on some conditions but I have not found what was the > consequences for a function being tagged one way or the other. Is > anyone can explain? As a programmer, there is no difference at all. For a compiler, the difference is that it can take some shortcuts if a function is tagged as trivial. For a default constructor, for example, if it is a trivial constructor, the compiler can choose not to call it at all, but initialise the memory in some other fashion that has the same end result. With a non-trivial constructor, the compiler must do the initialisation by the book, because there probably is some non-trivial action buried somewhere, like allocating additional memory. > > Greetings, > Olivier Langlois > http://www.olivierlanglois.net > http://blog.olivierlanglois.net > Bart v Ingen Schenau -- a.c.l.l.c-c++ FAQ: http://www.comeaucomputing.com/learn/faq c.l.c FAQ: http://c-faq.com/ c.l.c++ FAQ: http://www.parashift.com/c++-faq-lite/ [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Alberto Ganesh Barbati on 5 Apr 2008 04:43 Olivier Langlois ha scritto: > Those functions are the default constructor, the copy constructor and > the assignement operator. > > In the standard document (section 12), it is written that these > functions are implicitly declared, and implicitly defined *if* they > are used. Since they are defined on a usage basis, I am guessing that > they have internal linkage and that there could be many occurances of > these functions if they are used in more than 1 translation unit. Is > this correct? No. Unless the class has internal linkage, all its member functions have external linkage (3.5/5). You are confusing "internal linkage" with "inline". Implicitly-declared special functions are declared inline. If the same function with external linkage is defined in several translation units then you get several copies of the *same* function. In this case the function *must* be declared inline, otherwise it would violate the One Definition Rule. Oppositely, if the function has internal linkage (for example because it's declared in an anonymous namespace) then you get several different, albeit identical, functions. > If it is, would that be correct to say that if you want to make a > program smaller, you should explicitly declare and define those > functions even if they are identical than those that the compiler > would generate to give them external linkage and to avoid multiple > copies? No. The linker shall always strip multiple copies of the same function, so that the executable will end up containing at most one copy. If the function is very small, however, it may be expanded inline so that there won't be any copy of it left in the executable. > Also, the standard categorize these functions as trivial or non- > trivial based on some conditions but I have not found what was the > consequences for a function being tagged one way or the other. Is > anyone can explain? Basically, if a special function is trivial it does nothing. A trivial function exists only for semantic purposes but it doesn't emit any code at all. HTH, Ganesh -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Alf P. Steinbach on 5 Apr 2008 23:57
* Daniel Kr�gler: > On 4 Apr., 21:25, Olivier Langlois <olangl...(a)sympatico.ca> wrote: >> Those functions are the default constructor, the copy constructor and >> the assignement operator. >> >> In the standard document (section 12), it is written that these >> functions are implicitly declared, and implicitly defined *if* they >> are used. Since they are defined on a usage basis, I am guessing that >> they have internal linkage and that there could be many occurances of >> these functions if they are used in more than 1 translation unit. Is >> this correct? > > Any discussion about linkage of constructors is irrelevant, because > these entities have no associated linkage. Linkage requires the > existence > of a name: > > [basic.link]/2: "A name is said to have linkage when it might denote > the same > object, reference, function, type, template, namespace or value as a > name > introduced by a declaration in another scope" > > Constructors do not have names, > > [class.ctor]/1: "Constructors do not have names.[..] Hm de dum. Rather than making the question irrelevant, this observation only makes it more relevant. In practice, for the tools, there is and must be linkage of constructors, and it seems you have uncovered a something that's akin to (but not necessarily quite) a defect in the standard. It is perhaps not quite a defect, because we can live with a formal notion of linkage that doesn't include all relevant aspects of the practical notion, and in fact we have lived with that inconsistency. Another such mismatch is the linkage of static member functions, which can't be declared extern "C", which is OK for name mangling but very not-OK for static type checking. For practical purposes "all" compilers must support some non-standard way of using those pointers to static member functions as if they were extern "C" functions (otherwise no way to make a C callback internal in a module), and some compilers do that simply by not enforcing the standard's rules by default. But perhaps the above observation can help remove that ugly and so confusing to so many kludge about "no name". At least, one may wish. :-) > Constructors are also not addressable, > > [class.ctor]/12: "[..] The address of a constructor shall not be > taken." Note that this is a category error. Addressability in the above sense is about what the C++ programmer can do within the standard's language. Adressability in the sense the compiler needs to implement that language, e.g. for linking, is something else. > The concept of linkage is not related to the fact whether something > is implicitly declared or defined, used or not. Well it might be, I'm not sure, but that's a different discussion. Cheers, & hth., - Alf -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |