This is the mail archive of the cygwin mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

RE: <sys/sysmacros.h> is broken


Eric:
     I suggest adding a brief comment explaining the need for the
static.
     (For the lists, we had a brief off-list discussion, where Eric
quoted
C99 section 6.2.2 paragraph 5 and section 6.7.4 paragraph 6.  Together
they give the details needed for understanding.  In short, the compiler
can
choose not to in-line the function, but without the static it would emit
an
external function call--which can fail at link if that function does not
exist.  With the static, it can still choose to not in-line, but is
required
to provide a local function call within that translation unit.  I
apologize
for the off-list stuff, but the lists bounced my response and I've now
figured out how to get around that.)
				Craig

-----Original Message-----
From: newlib-owner=sourceware.org On Behalf Of Eric Blake
Sent: Wednesday, February 08, 2012 3:30 PM
To: cygwin=cygwin.com; newlib=sourceware.org
Subject: Re: <sys/sysmacros.h> is broken

On 02/08/2012 07:06 AM, Corinna Vinschen wrote:
> On Feb  8 06:33, Eric Blake wrote:
>> STC showing that sysmacros doesn't work when included indirectly in
C99
>> mode:
>>
>> $ cat foo.c
>> #include <sys/types.h>
>> int main() { return makedev(0,0); }
>> $ gcc -o foo foo.c
>> $ gcc -o foo foo.c --std=c99
>> /tmp/ccT40f0H.o:foo.c:(.text+0x1e): undefined reference to
>> `_gnu_dev_makedev'
>> collect2: ld returned 1 exit status
> 
> And why is that so?
> 
> Here's the definition of _ELIDABLE_INLINE in _ansi.h:
> 
>   /*  The traditional meaning of 'extern inline' for GCC is not
>     to emit the function body unless the address is explicitly
>     taken.  However this behaviour is changing to match the C99
>     standard, which uses 'extern inline' to indicate that the
>     function body *must* be emitted.  If we are using GCC, but do
>     not have the new behaviour, we need to use extern inline; if
>     we are using a new GCC with the C99-compatible behaviour, or
>     a non-GCC compiler (which we will have to hope is C99, since
>     there is no other way to achieve the effect of omitting the
>     function if it isn't referenced) we just use plain 'inline',
>     which c99 defines to mean more-or-less the same as the Gnu C
>     'extern inline'.  */
>   #if defined(__GNUC__) && !defined(__GNUC_STDC_INLINE__)
>   /* We're using GCC, but without the new C99-compatible behaviour.
*/
>   #define _ELIDABLE_INLINE extern __inline__ _ATTRIBUTE
((__always_inline__))
>   #else
>   /* We're using GCC in C99 mode, or an unknown compiler which 
>     we just have to hope obeys the C99 semantics of inline.  */
>   #define _ELIDABLE_INLINE __inline__
>   #endif
> 
> I really don't care for strict compiler modes, but shouldn't that
> have taken care of the problem?  If not, PTC.

After re-reading http://gcc.gnu.org/onlinedocs/gcc/Inline.html, I think
I understand what's going on.

In default mode, we get gcc's extern inline behavior, which says to only
use the definition in inline contexts (and contexts that can't be
inlined, such as taking the address of the function, will cause a link
failure unless cygwin.din provides a non-inline version in the library).

But in C99 mode, we get just 'inline', which says that we want to inline
use of the function, but also says that other code might want to link
against the function, so also output the function body.  The only time
the function body is not output is if you _also_ use 'static' with
inline.  I think the link error is resulting because we are not
providing a non-inline variant, but we also said the function is not
static, so the linker is trying to ensure that it has an entry point
even though we didn't provide one.

Any objections to this patch?  I tested that it solves my particular
test case.

diff --git i/newlib/ChangeLog w/newlib/ChangeLog
index 330f53c..faa1cf0 100644
--- i/newlib/ChangeLog
+++ w/newlib/ChangeLog
@@ -1,3 +1,7 @@
+2012-02-08  Eric Blake  <eblake=redhat.com>
+
+	* libc/include/_ansi.h (ELIDABLE_INLINE): Also include static.
+
 2012-02-07  Corinna Vinschen  <vinschen=redhat.com>

 	* libc/include/inttypes.h: Redefine pointer type macros.
diff --git i/newlib/libc/include/_ansi.h w/newlib/libc/include/_ansi.h
index e584ec3..5f0ced4 100644
--- i/newlib/libc/include/_ansi.h
+++ w/newlib/libc/include/_ansi.h
@@ -125,9 +125,9 @@
 /* We're using GCC, but without the new C99-compatible behaviour.  */
 #define _ELIDABLE_INLINE extern __inline__ _ATTRIBUTE
((__always_inline__))
 #else
-/* We're using GCC in C99 mode, or an unknown compiler which
+/* We're using GCC in C99 mode, or an unknown compiler which
   we just have to hope obeys the C99 semantics of inline.  */
-#define _ELIDABLE_INLINE __inline__
+#define _ELIDABLE_INLINE static __inline__
 #endif

 #endif /* _ANSIDECL_H_ */


-- 
Eric Blake   eblake=redhat.com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]