http://www.pronix.de -> Forum -> Knobelecke

Forum: Knobelecke

Moderatoren: broesel, juergen

Thema: [EDIT] - Function pointers

[EDIT] - Function pointers

icefire am 09.01.2012 um 22:02

Hallo zusammen,

Neulich auf der Uni kam wieder mal die Diskussion über die C-Syntax in Verbindung mit Function Pointer, ein Thema dass ich immer wieder im Internet nachlesen muss ...
Beim rumspielen ist mir folgendes Rätsel eingefallen:

Teil 1 (eher leicht):

Gegeben sei folgender Sourcecode:


#include <stdio.h>

void bar( void )
{
	printf( "%s\n", __func__ );
}

void foo( void (*pF)(void) )
{
	if( NULL != pF )
		pF();
}

int main( int argc, char *argv[] )
{
	foo( &*&*&*&*&bar );
}


Ist das gültige C-Syntax?
Falls nein, worüber würde ein Compiler meckern?
Würde zB das Kompilieren per GCC mit "gcc -Wall" Warnungen bringen?

Das Ganze kann natürlich jeder selbst ausprobieren, was aber im Rahmen dieses Rätsel als Schummeln gewertet und mit dem Tod bestraft wird Grafik: Smilie Teuflisch
Antworten also bitte aus dem Bauch heraus ohne vorheriges ausprobieren Grafik: Smilie Zwinker

Teil 2 (schwer):

Warum bzw. warum nicht ist das so?
Antworten auf diesen Teil des Rätsels sollten bevorzugt mit Bezug auf den C99-Standard[1] begründet werden Grafik: Smilie Gluecklich.

mfg, Wolfgang

[1] http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1256.pdf (externer link)

--
Hex, Bugs and Rock 'n Roll

 

Re: Function pointers

Patrick am 10.01.2012 um 08:15

Hallo Wolfgang,

aufgrund deiner Fragestellung vermute ich, dass das keine gültige C-Syntax ist.
Ich könnte mir vorstellen, dass der Adressoperator eine höhere Wertigkeit besitzt, als der Dereferenzierungsoperator.
Demnach soll eine Adresse von einer Adresse von einer Adresse von einer Adresse von einer Adresse eines Speicherbereichs übergeben werden.
Den Funktionszeiger ****bar gibt es aber nicht.

Gruß,
Patrick-Oliver

--
To follow the path: look to the master, follow the master, walk with the master, see through the master, become the master.

 

Re: Function pointers

icefire am 10.01.2012 um 22:43

Hallo Patrick-Oliver,

ich werd mit der Auflösung des Rätsels noch ein wenig warten, für den Fall dass andere Forenteilnehmer noch eine Meinung dazu haben :)

lg,
Wolfgang

--
Hex, Bugs and Rock 'n Roll

 

Re: Function pointers

Anonym am 16.01.2012 um 21:43

Hallo,

ok, jetzt zur Auflösung:

Zitat:

Ist das gültige C-Syntax?
Falls nein, worüber würde ein Compiler meckern?
Würde zB das Kompilieren per GCC mit "gcc -Wall" Warnungen bringen?


Ja, das ist tatsächlich gültige C-Syntax. Laut C-Standard heben sich ein '&' und ein '*' gegenseitig auf, d.h. so wie ich den Standard interpretiere sollte von dem Konstrukt &*&*&*&bar 3 mal &* entfernt werden, und nur noch &bar überbleiben:

Zitat:

6.5.3.2 Address and indirection operators

Constraints

The operand of the unary & operator shall be either a function designator, the result of a
[] or unary * operator, or an lvalue that designates an object that is not a bit-field and is
not declared with the register storage-class specifier.
The operand of the unary * operator shall have pointer type.

Semantics

The unary & operator yields the address of its operand. If the operand has type ‘‘type’’,
the result has type ‘‘pointer to type’’. If the operand is the result of a unary * operator,
neither that operator nor the & operator is evaluated and the result is as if both were
omitted
, except that the constraints on the operators still apply and the result is not an
lvalue. Similarly, if the operand is the result of a [] operator, neither the & operator nor
the unary * that is implied by the [] is evaluated and the result is as if the & operator
were removed and the [] operator were changed to a + operator. Otherwise, the result is
a pointer to the object or function designated by its operand.


Zitat:

Warum bzw. warum nicht ist das so?


Siehe vorherige Antwort.


--------------------------------------------------------------------


Die Lösung des Rätsel hatte somit nicht direkt mit Function-Pointern zu tun. Die Syntax von Function Pointern ist aber der Grund warum ich überhaupt auf die Idee gekommen bin so einen Funktionsaufruf zu konstruieren. Ich bin mir nie sicher ob man einer Funkion, die einen Function Pointer erwartet, einen Funktionsnamen (zB bar) übergeben darf, oder die Adresse eines Funktionsnamen (zB &bar).

Ich *glaube*, man darf beides, und beides sollte das gleiche sein. Herumspielen mit dem GCC widerlegt diese Vermutung zumindest nicht. So liefert zB folgendes Programm


#include <stdio.h>

void bar( void )
{
	printf( "%s\n", __func__ );
}

void foo( void (*pF)(void) )
{
	printf( "%s\n", __func__ );
	
	if( NULL != pF )
		pF();
}

int main( int argc, char *argv[] )
{
	foo( bar );
	foo( &bar );
	foo( *bar );
	foo( &*&*&*&*&bar );
	
	if( bar == &bar )
		printf( "Equal\n" );
	else
		printf( "Different\n" );
	
	if( bar == *bar )
		printf( "Equal\n" );
	else
		printf( "Different\n" );
	
	if( &bar == *bar )
		printf( "Equal\n" );
	else
		printf( "Different\n" );
	
	return	0;
}


diese Ausgabe:

TTY

you@host > ./a.out

foo

bar

foo

bar

foo

bar

foo

bar

Equal

Equal

Equal



Ich konnte aber trotz intensiver Suche im C-Standard keine eindeutige Bestätigung/Widerlegung finden ... Grafik: Smilie Traurig
Was ich finden konnte, was eventuell damit zu tun hat ist folgendes:

Zitat:

6.3.2 Other operands
6.3.2.1 Lvalues, arrays, and function designators

<...>

A function designator is an expression that has function type. Except when it is the
operand of the sizeof operator54) 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’’.


Falls jemand zu diesem Thema eine Meinung hat, ich bin sehr interessiert!


Mfg, Wolfgang