Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Crazy but valid C...

95 views
Skip to first unread message

umesh.k...@gmail.com

unread,
Jan 21, 2014, 3:12:34 AM1/21/14
to
Hi All,

Below code is that valid C Construct for the functions call .

int test()
{
printf("test\n");
}

int main()
{
(***(int(****)(void))test)();
}

Thanks for the inputs
~Umesh

Xavier Roche

unread,
Jan 21, 2014, 3:32:11 AM1/21/14
to
On 01/21/2014 09:12 AM, umesh.k...@gmail.com wrote:
> Below code is that valid C Construct for the functions call .
> (***(int(****)(void))test)();

(valid, but does not build with -Werror and proper warnings due to
strict aliasing issues)

This is due to the "A declaration of a parameter as "function returning
type" shall be adjusted to "pointer to function returning type"" rule,
and the obscure 6.3.2.1 4: “A function designator is an expression that
has function type. Except when it is the operand of the sizeof operator,
the _Alignof operator, or the unary & operator, a function designator
with type “function returning type” is converted to an expression that
has type “pointer to function returning type”

The wording is anything but clear, but unless I missed something, it
basically means that & and * yield the same pointer location for functions.

Ben Bacarisse

unread,
Jan 21, 2014, 6:57:29 AM1/21/14
to
umesh.k...@gmail.com writes:

> Below code is that valid C Construct for the functions call .
>
> int test()
> {
> printf("test\n");
> }
>
> int main()
> {
> (***(int(****)(void))test)();
> }

No not valid. Tidied up and simplified to show the problem:

#include <stdio.h>

int test(void) { printf("test\n"); }

int main(void)
{
(*(int(**)(void))test)();
}

The type int(*)(void) is a function pointer type. The type
int(**)(void) is an object pointer type. The conversion is not defined
to be meaningful, and de-referencing the resulting pointer is almost
certainly going to go horribly wrong. Doing that multiple times just
makes the matter worse.

What does your compiler say about it? If it is silent -- ask for more
warnings. For gcc, -pedantic disables GNU extensions and makes gcc
report this problem.

--
Ben.

Keith Thompson

unread,
Jan 21, 2014, 12:33:35 PM1/21/14
to
Xavier Roche <xro...@free.fr.NOSPAM.invalid> writes:
> On 01/21/2014 09:12 AM, umesh.k...@gmail.com wrote:
>> Below code is that valid C Construct for the functions call .
>> (***(int(****)(void))test)();
>
> (valid, but does not build with -Werror and proper warnings due to
> strict aliasing issues)
>
> This is due to the "A declaration of a parameter as "function returning
> type" shall be adjusted to "pointer to function returning type"" rule,
> and the obscure 6.3.2.1 4: “A function designator is an expression that
> has function type. Except when it is the operand of the sizeof operator,
> the _Alignof operator, or the unary & operator, a function designator
> with type “function returning type” is converted to an expression that
> has type “pointer to function returning type”

The _Alignof case does not apply, since (for unclear reasons) the
_Alignof operator can be applied only to a parenthesized type name, not
to an expression. This is unlike the sizeof operator. The reference to
_Alignof (for both array and function expressions) is an error in the
N1570 draft, corrected in the released 2011 ISO C standard.

--
Keith Thompson (The_Other_Keith) ks...@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
0 new messages