From owner-freebsd-current@FreeBSD.ORG Tue Nov 12 19:54:46 2013 Return-Path: Delivered-To: freebsd-current@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 454DB278; Tue, 12 Nov 2013 19:54:46 +0000 (UTC) Received: from bigwig.baldwin.cx (bigwig.baldwin.cx [IPv6:2001:470:1f11:75::1]) (using TLSv1 with cipher ADH-CAMELLIA256-SHA (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id 19174212E; Tue, 12 Nov 2013 19:54:46 +0000 (UTC) Received: from jhbbsd.localnet (unknown [209.249.190.124]) by bigwig.baldwin.cx (Postfix) with ESMTPSA id 3213FB943; Tue, 12 Nov 2013 14:54:44 -0500 (EST) From: John Baldwin To: freebsd-current@freebsd.org Subject: Re: Are clang++ and libc++ compatible? Date: Tue, 12 Nov 2013 13:21:07 -0500 User-Agent: KMail/1.13.5 (FreeBSD/8.4-CBSD-20130906; KDE/4.5.5; amd64; ; ) References: <20131112163219.GA2834@troutmask.apl.washington.edu> <20131112165422.GA2939@troutmask.apl.washington.edu> In-Reply-To: MIME-Version: 1.0 Content-Type: Text/Plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit Message-Id: <201311121321.07330.jhb@freebsd.org> X-Greylist: Sender succeeded SMTP AUTH, not delayed by milter-greylist-4.2.7 (bigwig.baldwin.cx); Tue, 12 Nov 2013 14:54:45 -0500 (EST) Cc: Eitan Adler , David Chisnall , Steve Kargl X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.16 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 12 Nov 2013 19:54:46 -0000 On Tuesday, November 12, 2013 1:11:04 pm Eitan Adler wrote: > On Tue, Nov 12, 2013 at 11:54 AM, Steve Kargl > wrote: > > On Tue, Nov 12, 2013 at 04:38:17PM +0000, David Chisnall wrote: > >> On 12 Nov 2013, at 16:32, Steve Kargl wrote: > >> > >>> Trying to build news/pan with clang++ dies with > >>> > >>> gmake[3]: Entering directory `/usr/ports/news/pan/work/pan-0.139/pan/general' > >>> CXX file-util.o > >>> In file included from file-util.cc:38: > >>> In file included from ./log.h:26: > >>> /usr/include/c++/v1/deque:907:49: error: invalid application of 'sizeof' to an > >>> incomplete type 'value_type' (aka 'pan::Log::Entry') > >>> static const difference_type __block_size = sizeof(value_type) < 256 ? 4... > >>> > >>> Anyone know how to fix either clang++ or libc++? > >> > >> The error here does not appear to be in clang or libc++, but in the > >> use by the thing that you are compiling. > >> This is saying that you have tried to create a std::dequeu, > >> but pan::Log::Entry is a forward declaration and so the template > >> instantiation fails. > >> The fix is to move the definition of pan::Log::Entry such that it > >> is visible at the time of its use. > >> > > > > I don't know C++, but it is at all like C, then the header files > > are normally placed at the top of a file before one's code. In > > this case, the code in news/pan/work/pan-0.139/pan/general/log.h > > looks like (where I've striped comment to keep it short) > > > > #ifndef __Log_h__ > > #define __Log_h__ > > > > #include > > #include > > #include > > #include > > > > namespace pan > > { > > class Log > > { > > public: > > enum Severity { > > PAN_SEVERITY_INFO = 1, > > PAN_SEVERITY_ERROR = 2, > > PAN_SEVERITY_URGENT = (1<<10) > > }; > > > > struct Entry { > > time_t date; > > Severity severity; > > std::deque messages; > > std::string message; > > bool is_child; > > Entry() : is_child(false) { } > > }; > > > > void add_entry(Entry& e, std::deque& list); > > > > > > Are you saying that I need to move '#include ' to > > the location above the 'void add_entry(...)' line? > > The problem here is that the code is trying to make a std::deque of > the type Entry before Entry is fully defined. > This is nearly identical to the problem in the simplified C code below: > > struct foo { > struct foo bar; > } Except it isn't. It's declaring the head of a container. This is more like: struct foo { TAILQ_HEAD(, foo) messages; }; The problem is that unlike the queue macros (which are broken out into chunks), the compiler has to instantiate all of std::deque<> even though it will only use a portion of its definition. I understand why this is a limitation of C++, but it's not quite as brain damaged as your example. The above would not be unreasonable if the foo objects should be stored in a tree and messages was a list of the child nodes. Depending on how this library works you might be able to shim around this by having the dequeue store pointers instead of Entry structs. -- John Baldwin