Re: determine base type of a typedef

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 2020-10-23, Nick Bowler <nbowler@xxxxxxxxxx> wrote:
> On 23/10/2020, Paul Eggert <eggert@xxxxxxxxxxx> wrote:
>> On 10/22/20 6:09 PM, Russell Shaw wrote:
>>>     else if(sizeof(time_t) == sizeof(long int)) {
>>
>> This is not the right kind of test. You want to test whether time_t and
>> int
>> are
>> the same types, not whether they're the same size. To do that, you should
>> use
>> code like this:
>>
>> extern time_t foo;
>> extern long int foo;
>>
>> Of course this means you'll need to compile N programs rather than
>> one, but that's life in the big Autoconf city.
>
> To improve configure performance when N is more than one or two,
> you can use C11 _Generic and AC_COMPUTE_INT to pretty easily and
> quickly determine which type (out of a finite list of candidates)
> time_t or any other type is compatible with.
>
> But you'd need a fallback (probably by compiling one program
> like the one shown abovce for each type) to handle the case
> where _Generic is not supported by the implementation.
>
> Example (totally untested):
>
>   AC_COMPUTE_INT([timetype],
>     [_Generic((time_t)0, long long: 3, default: 0)
>       + _Generic((time_t)0, long: 2, default: 0)
>       + _Generic((time_t)0, int: 1, default: 0)],

On review, it is obvious this list of types could be more succinctly
written with a single _Generic as they are all for sure different:

  _Generic((time_t)0, long long: 3, long: 2, int: 1, default: 0)

But care must be taken if any of the generic cases are themselves
typedefs, (for example, if we wanted to determine whether POSIX
ssize_t is compatible with a list of types that includes ptrdiff_t),
as it is an error to include compatible types among the list of
cases:

  /* error if ptrdiff_t happens to be compatible with long long */
  _Generic((ssize_t)0, long long: 2, ptrdiff_t: 1, default: 0)

Nesting avoids this problem better than adding as I did originally:

  _Generic((ssize_t)0, long long: 2, default:
    _Generic((ssize_t)0, ptrdiff_t: 1, default: 0))

as only one "branch" can be matched.

>     [#include <time.h>],
>     [... slow fallback computation goes here])
>
>   AS_CASE([$timetype],
>     [3], [... action when time_t is compatible with long long],
>     [2], [... action when time_t is compatible with long],
>     [1], [... action when time_t is compatible with int],
>     [... action when time_t's compatibility is undetermined])

Cheers,
  Nick




[Index of Archives]     [GCC Help]     [Kernel Discussion]     [RPM Discussion]     [Red Hat Development]     [Yosemite News]     [Linux USB]     [Samba]

  Powered by Linux