Która z tych odpowiedzi dotyczących funkcji jest nieprawidłowa?

17

Dlatego podczas długich kompilacji zdecydowałem się na ogólny test C ++ na ODesk i natknąłem się na to pytanie.

To pytanie

Jeśli się nie mylę, biorąc pod uwagę sformułowanie (lub jego brak), wszystkie z nich mogą być prawdziwe.

za.

int Foo() { }
int Foo(int bar) { }

b. Cóż, return void;byłoby niepoprawne semantycznie, ale funkcje mogą oczywiście mieć voidtypy zwracane.

void Foo() { }

do. To jest definicja funkcji wbudowanych, tak.

re. Bez wchodzenia w szczegółowe informacje na temat rozmieszczenia następujących elementów,

typedef void (*Func)(int);

Func functions[2];

void Foo(int bar) { }
void Bar(int foo) { }

functions[0] = &Foo;
functions[1] = &Bar;

Ponadto zawsze można to zrobić za pomocą lambd i funktorów .

mi.

void Foo(int& bar)
{
    ++bar;
}

int foobar = 5;
Foo(foobar);

fa.

int bar = 5;

int& GetBar()
{
    return bar;
}

GetBar() = 6;

sol.

int bar = 5;

int* GetBar()
{
    return &bar;
}

(*GetBar()) = 5;

Nie widzę, gdzie to pytanie ma naprawdę fałszywe odpowiedzi. Czy coś brakuje?

Nie trzeba dodawać, że zabrakło mi czasu i wszystko mi się nie udało. Chyba jestem złym programistą C ++. :(

Qix
źródło
18
Przybyłem tutaj, aby krzyknąć na dziecko wklejające pracę domową, było mile zaskoczone.
SomeKittens,
W rzeczywistości nie wszystkie języki wymagają rozszerzenia funkcji wbudowanych. „inline” to wskazówka kompilatora, a nie polecenie w Delphi, a C, C ++ mają wyjątki . Zatem „c” może być również fałszywe. Bardziej zabawne może być napisanie odpowiedzi pokazującej, w jaki sposób każda instrukcja może być błędna.
Móż
1
@ Ᶎσᶎ Gdyby tylko było pole tekstowe. Chcę wrócić i kliknąć „Zgłoś problem z tym pytaniem”.
Qix
5
To nie jest tablica funkcji. To tablica wskaźników funkcji.
user253751
@immibis Prawda, ale pytanie tak naprawdę nie wyjaśnia (przynajmniej dla mnie tak nie było).
Qix

Odpowiedzi:

21

Całe to pytanie jest niejasne. Zestawienie pytań sugeruje możliwość wielokrotnego wyboru, a przyciski opcji wskazują jeden wybór.

Co więcej, b jest dość podejrzane, ponieważ funkcje void niczego nie zwracają.

D jest również wątpliwe, ponieważ o ile mi wiadomo, nie możesz mieć szeregu funkcji. Jasne, możesz mieć tablicę wskaźników funkcji, ale to nie jest dokładnie to samo.

Jaka jest nazwa?
źródło
Dobrze; D jest jak pytanie, czy możesz zadzwonić int. Jasne, jeśli rzucisz go na wskaźnik, a ten wskaźnik odnosi się do funkcji ...
Qix
1
Jestem gotów się założyć, że D jest odpowiedzią, na którą czekają, ale tak, pytanie jest słabe.
Gort the Robot
Chociaż voidfunkcje nie zwracają żadnej wartości , nadal zwracają typ void . Dlatego mówię, że B jest prawdą.
Thomas Eding
@ThomasEding To wciąż bardzo złe sformułowanie z ich strony. Ty nie return void;, ale zamiast tego return;.
Qix
10

Odpowiedź c) jest również prawdopodobnie fałszywa.

„Funkcje wbudowane są rozszerzane podczas kompilacji, aby uniknąć narzutu wywołania”.

Po pierwsze, kompilator C ++ może ignorować inlinepodpowiedź, nie rozszerzając wcale funkcji.

Po drugie, podany „powód” ekspansji jest nadmiernym uproszczeniem. W rzeczywistości prawdziwy powód dokonania rozszerzenia (lub nie) jest całkowicie w rękach autora kompilatora.

Stephen C.
źródło
Jesteś poprawne, ale myślałem o nim w sensie „okay, kompilator ustaliła, że nie chcą inline funkcję” raczej niż inlinepodpowiedź.
Qix
Kompilator nie może całkowicie zignorować podpowiedzi. Przynajmniej jest to obowiązkowy efekt, stanowiący wyjątek od ODR.
Deduplicator,
@Deduplicator - Tak, może. „Bez względu na to, jak wyznaczysz funkcję jako wbudowaną, jest to żądanie, które kompilator może zignorować: kompilator może wbudować-rozwinąć niektóre, wszystkie lub żadne z miejsc, w których wywołujesz funkcję oznaczoną jako wbudowaną”. - źródło isocpp.org/wiki/faq/Inline-Functions
Stephen C
@StephenC: Tak, można zignorować prośbę o rozwinięcie go w linii. Powiedziałem tylko, że wyraźny wyjątek od ODR nie może.
Deduplicator
Widzę. Zaktualizowałem brzmienie mojej odpowiedzi
Stephen C
7

do. To jest definicja funkcji wbudowanych, tak.

To nie do końca prawda.
Mimo nazwy słowo kluczowe inlinenie gwarantuje wstawienia funkcji. Jedyne, czego możesz być pewien, to to, że kompilator nie narzeka, jeśli zobaczy definicję funkcji wbudowanej wiele razy.

Tak więc, ściśle mówiąc, opcja C jest niepoprawna, ale nie sądzę, że jest to odpowiedź, której oczekują autorzy quizu, ponieważ istnieje odpowiedź, która jest jeszcze bardziej błędna.

re. Bez wchodzenia w szczegółowe informacje na temat rozmieszczenia następujących elementów,

typedef void (*Func)(int);

Func functions[2];

void Foo(int bar) { }
void Bar(int foo) { }

functions[0] = &Foo;
functions[1] = &Bar;

Ponadto zawsze można to zrobić za pomocą lambd i funktorów.

W twoim przykładzie functionsjest tablica wskaźników do funkcji, a nie tablica samych funkcji. Podobnie lambdy i funktory też nie są tak naprawdę funkcjami. Są to klasy, które odpowiadają operatorowi wywołania funkcji, ale to nie czyni ich funkcjami w oczach definicji języka C ++.

Funkcje w C ++ są trochę jak obywatele drugiej kategorii. Możesz je zdefiniować i wywołać, ale gdy tylko spróbujesz zrobić coś innego z typem funkcji (np. Utworzyć ich tablicę), albo pojawi się błąd, albo dyskretnie przekonwertują się we wskaźniku.

Bart van Ingen Schenau
źródło
Zgadzam się z bitem D, ale czytałem cjako funkcje, które zostały już pozytywnie oznaczone do wstawiania, w porównaniu do inlinesamego słowa kluczowego. Rozumiem, że inlineto podpowiedź.
Qix
4

Jeśli cokolwiek, musiałoby to być b . Nie można , ale można zwróci . W deklaracji funkcji powinna znajdować się pustka, aby powiadomić kompilator o braku zwracanej wartości.returnvoidnull

Typ pustki

W C i C ++

Funkcja z pustym typem wyniku kończy się po osiągnięciu końca funkcji lub wykonaniu instrukcji return bez zwracanej wartości. Typ void może również pojawiać się jako jedyny argument prototypu funkcji, wskazując, że funkcja nie przyjmuje argumentów. Zauważ, że pomimo nazwy, we wszystkich tych sytuacjach, typ pustki służy jako typ jednostki, a nie jako typ zerowy lub dolny, nawet jeśli w przeciwieństwie do prawdziwego typu jednostki, który jest singletonem, typ pustki zawiera pustą zestaw wartości, a język nie zapewnia żadnego sposobu deklarowania obiektu ani reprezentowania wartości typu void.

Adam Zuckerman
źródło
2
-1: Chociaż voidfunkcje nie zwracają żadnej wartości , nadal zwracają typ void . Dlatego mówię, że B jest prawdą.
Thomas Eding
Zwrot nieważności jest dozwolony w niektórych okolicznościach. Zobacz tutaj .
Josh Kelley,