2012-11-18 18 views
5

Powiel możliwe:
Casting a function pointer to another typeCzy przekazuje dodatkowe parametry za pomocą wskaźnika funkcji legal/zdefiniowanego w C?

Załóżmy zainicjować wskaźnik funkcji z funkcją, która faktycznie zajmuje mniej parametrów następnie definicji wskaźnik funkcji, będzie funkcja nadal działać prawidłowo, jeśli wywołana poprzez wskaźnik funkcji?

Próbowałem to z gcc i działał zgodnie z oczekiwaniami, ale zastanawiam się, czy to zachowanie jest spójne kompilatory/platform (i podejrzewam w niektórych środowiskach może siać spustoszenie na stosie):

#include <stdio.h> 

typedef void (*myfun)(int, int, int); 

void test_a(int x, int y, int z) { 
    printf("test_a %d %d %d\n", x, y, z); 
} 

void test_b(int x, int y) { 
    printf("test_b %d %d\n", x, y); 
} 

int main() { 
    myfun fp; 
    fp = test_a; 
    fp(1, 2, 3); 
    fp = (myfun) test_b; 
    fp(4, 5, 6); 
} 

Odpowiedz

4

zachowanie twojego programu jest niezdefiniowane. Fakt, że kompiluje się w ogóle, wynika z obsady, która skutecznie mówi kompilatorowi: "to jest złe, ale mimo to rób to". Jeśli usuniesz obsady, dostaniesz odpowiedni komunikat o błędzie: (. Od gcc -Wall -Werror)

a.c:17:8: error: assignment from incompatible pointer type [-Werror] 

Dokładniej, zachowanie zależy od konwencji telefonicznych. Jeśli byłeś na platformie, argumenty były przekazywane w kolejności "odwróconej" na stosie, program dałby zupełnie inny wynik.

+1

Może również ulec awarii, jeśli używane jest czyszczenie odświeżania. –

+0

Rozumiem. A co z definiowaniem typu wskaźnika funkcji bez listy parametrów, na przykład'typedef void (* myfun)() '. Czy w takim przypadku kompilator powinien zagwarantować, że kolejność parametrów na stosie będzie "właściwa"? – Askaga

+0

@BillAskaga Nie: "aby zagwarantować", co chcesz, być może musisz upewnić się, że funkcja target i wskaźnik funkcji używają konwencji wywoływania cdecl (http://en.wikipedia.org/wiki/X86_calling_conventions#cdecl). – ChrisW

10

Jest to niezdefiniowane zachowanie. Używaj na własne ryzyko. Został on podobno powodować Nasal Demons!

enter image description here

+0

To zdjęcie jest niesamowite. Tutaj oferuję oczyszczoną wersję i ślad wektorowy: https://www.dropbox.com/sh/c0f5htyg46jcels/AABD9Qaw2JlhMAKCycAek-9ia?dl=0 – wilx

+0

Lol. Dziękuję Ci.Opowiedziałem historię niezdefiniowanego zachowania mojej ulubionej córce, która lubi doodle. Wysłała mi to następnego dnia. Jest po prostu tyle do pokochania. – EvilTeach

+0

Oto JPG: http://imgur.com/gallery/Zomm1zq/new – wilx

3

Wywołanie funkcji jest niezdefiniowanym zachowaniem.

(C99, 6.3.2.3p8) "[...] Jeśli przekonwertowany wskaźnik jest używany do wywołania funkcji, której typ nie jest zgodny z typem wskazanym, zachowanie jest niezdefiniowane."

Dla informacji należy zauważyć, że rodzaj funkcja:

(C99 6.2.5p20) „[...] opisuje funkcję z określonego typu powrotnego typ funkcja charakteryzuje. jego typ zwrotu oraz liczba i typy jego parametrów. "

Powiązane problemy