This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Q.: inconsistent (?) warnings about functions called through non-compatible types
- From: Mikhail Maltsev <maltsevm at gmail dot com>
- To: Godmar Back <godmar at gmail dot com>
- Cc: gcc at gcc dot gnu dot org
- Date: Tue, 31 Mar 2015 04:13:25 +0300
- Subject: Re: Q.: inconsistent (?) warnings about functions called through non-compatible types
- Authentication-results: sourceware.org; auth=none
- References: <CAB4+JY+wKi2YniOOJLydB_Q6QHSE4f9i7x-Ld+dO6X0V9hApHg at mail dot gmail dot com> <87zj6v7ghd dot fsf at igel dot home> <CAB4+JY+gc8rLRP1e2b3_npeo36OzdoZJ0_phkAiOQ4cK_bJkzw at mail dot gmail dot com>
29.03.2015 23:18, Godmar Back writes:
> Thanks. I'm a bit confused then what constitutes defined & undefined behavior.
>
> The actual situation I encountered is best described by this example:
>
> --
> /* Tested with gcc 4.4.7 and 4.8.2 -m32 */
> #include <stdio.h>
> #include <stdbool.h>
>
> bool boolFunctionThatReturnsFalse() {
> // I'm faking this here, but a real 'bool' function could
> // place 0x100 in $eax when meaning to return false.
> register bool r asm("%eax");
> asm("mov $0x100, %eax");
> return r;
> }
>
> typedef int (*intFunction)(void);
>
> int
> main()
> {
> if ( boolFunctionThatReturnsFalse() )
> printf("true\n");
> else
> printf("false\n");
>
> intFunction f = (intFunction) boolFunctionThatReturnsFalse;
> if ( f() )
> printf("true\n");
> else
> printf("false\n");
> }
> --
>
> (I'm faking the return value of boolFunctionThatReturnsFalse here, but
> I have observed this behavior in actual code.)
>
> Is this defined or undefined behavior that my problem invokes?
>
> - Godmar
>
According to C99 standard:
1. A pointer to a function of one type may be converted to a pointer to
a function of another type and back again; the result shall compare
equal to the original pointer. If a converted pointer is used to call a
function whose type is not compatible with the pointed-to type, the
behavior is undefined. (6.3.2.3)
2. For two function types to be compatible, both shall specify
compatible return types. (6.7.5.3).
3. Two types have compatible type if their types are the same. (6.2.7)
4. The type char, the signed and unsigned integer types, and the
floating types are collectively called the basic types. Even if the
implementation defines two or more basic types to have the same
representation, they are nevertheless different types. (6.2.5)
Thus, the call of f() invokes undefined behavior.
--
Regards,
Mikhail Maltsev