public inbox for gcc-prs@sourceware.org help / color / mirror / Atom feed
From: philipp.bachmann@obtree.com To: gcc-gnats@gcc.gnu.org Subject: c++/3167: Copyconstructor not called when entering function (var args) Date: Wed, 13 Jun 2001 07:26:00 -0000 [thread overview] Message-ID: <20010613142131.4125.qmail@sourceware.cygnus.com> (raw) >Number: 3167 >Category: c++ >Synopsis: Copyconstructor not called when entering function (var args) >Confidential: no >Severity: serious >Priority: medium >Responsible: unassigned >State: open >Class: sw-bug >Submitter-Id: net >Arrival-Date: Wed Jun 13 07:26:01 PDT 2001 >Closed-Date: >Last-Modified: >Originator: Philipp Bachmann >Release: g++ 2.95.3 >Organization: >Environment: Sun Solaris 7 SPARC >Description: The code provided compiles successfully with the warnings: [583]$ g++ copyconstr2.c++ copyconstr2.c++: In function `int ellipses(char *, ...)': copyconstr2.c++:70: warning: cannot pass objects of type `base_t' through `...' copyconstr2.c++:70: warning: cannot pass objects of type `base_t' through `...' copyconstr2.c++: In function `int main()': copyconstr2.c++:84: warning: cannot pass objects of type `base_t' through `...' (These warnings are issued only if "base_t" explicitly has a copy constructor defined.) If the code is run, the following happens: [584]$ ./a.out "base_t::Constructor" called. Constructing 0xffbef2f0. "main()": Secret is 42. "ellipses()": Function entered. "base_t::Copyconstructor" called. Constructing 0xffbef260. "ellipses()": Strange: 42. "ellipses()": Function ending. "base_t::Destructor" called. Destroying 0xffbef260. "main()": Function call over. "base_t::Destructor" called. Destroying 0xffbef2f0. If I understand, what's behind the scene, when calling a function, correctly, then I expect a call to the copy constructor on entering the function, i.e. I would expect the hypothetical output [584]$ ./a.out "base_t::Constructor" called. Constructing 0xffbef2f0. "main()": Secret is 42. "base_t::Copyconstructor" called. Constructing 0xfoo. "ellipses()": Function entered. "base_t::Copyconstructor" called. Constructing 0xffbef260. "ellipses()": Strange: 42. "ellipses()": Function ending. "base_t::Destructor" called. Destroying 0xffbef260. "base_t::Destructor" called. Destroying 0xfoo. "main()": Function call over. "base_t::Destructor" called. Destroying 0xffbef2f0. There is no reason in my opinion, why the compiler needs any information about the argument types of the _function_ called (because there is a variable argument list, there is indeed no such information on all arguments but the first one) to call the copy constructor to put a copy of "base" onto the stack - the only information, the compiler needs to have (and it has, because "base" is defined as "base_t" two lines before the call to the "ellipses()" function) for calling the copy constructor is the type of "base". The call to the copyconstructor that can be seen, though, results from the initialization of local variable "base" inside of the function "ellipses()" and can easily be switched off by undefining "COPY". This is correct behaviour. I've compared g++'s behaviour with the one of Sun CC 6 Update 1 (unpatched). Sun's compiler calls the copyconstructor when entering the function, but has another bug: It never destoys the space constructed... >How-To-Repeat: [583]$ g++ copyconstr2.c++ [584]$ ./a.out >Fix: >Release-Note: >Audit-Trail: >Unformatted: ----gnatsweb-attachment---- Content-Type: text/plain; name="copyconstr2.c++.txt" Content-Disposition: inline; filename="copyconstr2.c++.txt" /* Very simple program to show two bugs in two different compilers: Sun Forte 6 Update 1 (unpatched) calls "base_t::base_t(const base_t &)" on calling "ellipses("",CAST base)" even if "CAST" is replaced by nothing - but will never call "base_t::~base_t(void)" to destroy the copyconstructed formal parameter; if "CAST" is defined to be "(base_t)", then "base_t::base_t(const base_t &)" is called twice, but "base_t::~base_t(void)" is called only once to destroy the temporary instance resulting from the cast operation. GNU g++ 2.95.3, however, only calles "base_t::base_t(const base_t &)", "on" entering the function, if the argument "base" in the function call is explicitly casted to its own type; expected behaviour was to always cast the copyconstructor at least once on entering the function. */ /* $Log: copyconstr2.c++,v $ * Revision 1.2 2001/06/13 14:55:15 bachlipp * Introduced "COPY" #define. Slightly presiced comment on * g++ behaviour. * * Revision 1.1 2001/06/13 10:34:26 bachlipp * Initial revision * */ static const char rcsid[]="@@(#)$Id: copyconstr2.c++,v 1.2 2001/06/13 14:55:15 bachlipp Exp $"; #include<iostream> #include<stdio.h> #include<cstdarg> #define CAST // #define CAST (base_t) #define COPY class base_t { public : base_t(void); base_t(const base_t &); virtual ~base_t(void); static const int secret; }; base_t::base_t(void) { std::cerr<<"\"base_t::Constructor\" called. Constructing "<<this<<"."<<std::endl; } base_t::base_t(const base_t &org) { std::cerr<<"\"base_t::Copyconstructor\" called. Constructing "<<this<<"."<<std::endl; } base_t::~base_t(void) { std::cerr<<"\"base_t::Destructor\" called. Destroying "<<this<<"."<<std::endl; } const int base_t::secret=42; int ellipses(char *fmt, ...); int ellipses(char *fmt, ...) { std::cerr<<"\"ellipses()\": Function entered."<<std::endl; int retval; va_list arg; va_start(arg,fmt); base_t base #ifdef COPY =va_arg(arg,base_t) #else ; base=va_arg(arg,base_t) #endif ; retval=fprintf(stderr,"\"ellipses()\": Strange: %d.\n",base.secret); va_end(arg); std::cerr<<"\"ellipses()\": Function ending."<<std::endl; return retval; } int main() { base_t base; std::cerr<<"\"main()\": Secret is "<<base.secret<<"."<<std::endl; ellipses("",CAST base); std::cerr<<"\"main()\": Function call over."<<std::endl; return 0; }
next reply other threads:[~2001-06-13 7:26 UTC|newest] Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top 2001-06-13 7:26 philipp.bachmann [this message] 2001-06-13 9:16 Artem Khodush 2001-06-14 19:00 rodrigc
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20010613142131.4125.qmail@sourceware.cygnus.com \ --to=philipp.bachmann@obtree.com \ --cc=gcc-gnats@gcc.gnu.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).