__CRT_INLINE why with extern ?

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

__CRT_INLINE why with extern ?

Roumen Petrov
I would like to post a patch for issue 2134161(time functions and types
for msvcrt > 7.1) but I enter into a issue that I don't know how to resolve.

Lets see the test program:
$ cat test-crt-inline.c:
#include <math.h>
typedef __int64 time_t;
__CRT_INLINE time_t __cdecl  time (time_t* _v)
        { return _time32 (_v); }


__inline__ time_t __cdecl  my_time (time_t* _v)
        { return _time32 (_v); }


void foo ( time_t __cdecl  (*f) (time_t* _v) ) {
   time_t v = 0;
   f (&v);
}


int main() {
{
   float v = 0.0;
   coshf(v);
}
#if 1
{
   time_t v = 0;
   time (&v);
}
#endif
{
   time_t v = 0;
   my_time (&v);
   foo(my_time);
}
   return (0);
}
------

Now lets see preprocessor output:
a) $ gcc -specs=msvcr90 -E -c test-crt-inline.c | grep -w coshf
extern __inline__ float __attribute__((__cdecl__)) coshf (float x)
   coshf(v);
-----
b) $ gcc -specs=msvcr90 -E -c test-crt-inline.c | grep -w time
extern __inline__ time_t __attribute__((__cdecl__)) time (time_t* _v)
   time (&v);
-----

So the definition for both functions is similar but for protocol there
is definition for coshf from math.h:
__CRT_INLINE float __cdecl coshf (float x) {return (float) cosh (x);}



The test program fail to link with linker error: undefined reference to
'_time'. It succeed for coshf since function is defined in mingwex library:
$ cat ./mingwex/math/coshf.c
#include <math.h>
float coshf (float x)
   {return (float) cosh (x);}
-----

But I can't use mingwex since _time32 finction is new for msvcrt >= 8.0.
If I omit extern from function declaration it is fine.


Roumen
P.S.: to get linker error you has to put msvcr90.dll in build directory
or to use modified libmsvcr90.a where time is replaced by _time32.

-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
MinGW-users mailing list
[hidden email]

You may change your MinGW Account Options or unsubscribe at:
https://lists.sourceforge.net/lists/listinfo/mingw-users
Reply | Threaded
Open this post in threaded view
|

Re: __CRT_INLINE why with extern ?

Brian Dessent
Roumen Petrov wrote:

> If I omit extern from function declaration it is fine.

"extern inline" on a definition tells gcc to use that definition only
for the purposes of inlining, but never emit and out-of-line copy of the
function body.  Plain "inline" both emits an out-of-line copy and uses
the definition for inlining.

Thus when you say "extern inline" what you are saying is "this is a
version of the function that you should use for any call site where it
can be inlined, but there is a separate callable library version of the
function elsewhere."  But if there is no separate library version
elsewhere then any callsite that couldn't be inlined will fail -- and
note that gcc does no inlining without optimization enabled (-O), so you
really can't use "extern inline" alone in a header without a
corresponding library function somewhere.

How about skipping the inlining business alltogether and just do this:

#if __MSVCRT_VERSION__ >= 0x0800
_CRTIMP time_t __cdecl __MINGW_NOTHROW  time (time_t*) \
   __asm__("__time32");
#else
_CRTIMP time_t __cdecl __MINGW_NOTHROW  time (time_t*);
#endif

Brian

-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
MinGW-users mailing list
[hidden email]

You may change your MinGW Account Options or unsubscribe at:
https://lists.sourceforge.net/lists/listinfo/mingw-users
Reply | Threaded
Open this post in threaded view
|

Re: __CRT_INLINE why with extern ?

JonY-2
On 10/13/2008 11:18, Brian Dessent wrote:

> Roumen Petrov wrote:
>
>> If I omit extern from function declaration it is fine.
>
> "extern inline" on a definition tells gcc to use that definition only
> for the purposes of inlining, but never emit and out-of-line copy of the
> function body.  Plain "inline" both emits an out-of-line copy and uses
> the definition for inlining.
>
> Thus when you say "extern inline" what you are saying is "this is a
> version of the function that you should use for any call site where it
> can be inlined, but there is a separate callable library version of the
> function elsewhere."  But if there is no separate library version
> elsewhere then any callsite that couldn't be inlined will fail -- and
> note that gcc does no inlining without optimization enabled (-O), so you
> really can't use "extern inline" alone in a header without a
> corresponding library function somewhere.
>

Also, how gcc handles the {extern,static} inline keywords depends on
whether it was set to C99 or C89 mode.

More here: <http://gcc.gnu.org/ml/gcc/2006-11/msg00006.html>

-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
MinGW-users mailing list
[hidden email]

You may change your MinGW Account Options or unsubscribe at:
https://lists.sourceforge.net/lists/listinfo/mingw-users
Reply | Threaded
Open this post in threaded view
|

Re: __CRT_INLINE why with extern ?

Brian Dessent
JonY wrote:

> Also, how gcc handles the {extern,static} inline keywords depends on
> whether it was set to C99 or C89 mode.

It also depends on the version of gcc, since the change in behavior for
-std=c99 was made during the 4.3 series and backported to 4.2, so prior
versions always have the GNU semantics for extern inline.   (The docs
say 4.1.3 but there never was such a version as the 4.1 branch was
closed before an additional release was ever made.)  When they made the
change they added two preprocessor defines, __GNUC_STDC_INLINE__ and
__GNUC_GNU_INLINE__, which code can use to determine if the GNU or ISO
semantics are in effect.

Brian

-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
MinGW-users mailing list
[hidden email]

You may change your MinGW Account Options or unsubscribe at:
https://lists.sourceforge.net/lists/listinfo/mingw-users
Reply | Threaded
Open this post in threaded view
|

Re: __CRT_INLINE why with extern ?

Roumen Petrov
In reply to this post by Roumen Petrov
Thanks to Brain and JonY for details.

Now for me is too difficult to decide what is reasonable:

1)
__CRT_INLINE  time_t __cdecl __MINGW_NOTHROW __attribute__((always_inline))
time (time_t* _v) { return _time32 (_v); }

2)
_CRTIMP time_t __cdecl __MINGW_NOTHROW  time (time_t*)
__asm__("__time32");

3)
static inline time_t __cdecl __MINGW_NOTHROW
time (time_t* _v) { return _time32 (_v); }


For 1) and 2) I couldn't identify where is used in mingw32/w32api
headers. w32api define FORCEINLINE[=__inline
__attribute__((always_inline))] but is not used.
Case 3) is used by example in stdlib.h/stdio.h but some time with
__inline__ for C-code.

The case 1) we may control with a new macro __CRT_FORCEINLINE that add
attribute always_inline to the existing __CRT_INLINE.

Roumen

-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
MinGW-users mailing list
[hidden email]

You may change your MinGW Account Options or unsubscribe at:
https://lists.sourceforge.net/lists/listinfo/mingw-users