funkcja typu A bez return, brak błędu.

0
class A { /* ... */ };
A foo () { /* ... */ };

int main()
{
     A a;
     a = foo();

     A a2 = foo();

    return 0;
}

kompilator nie zwraca błędu

Nie do końca rozumiem ten kod a właściwie w ogóle.

A foo () { /* ... */ }; <- czy to jest definicja funkcji? jeśli tak dlaczego kompilator nie zwraca błędu że funkcja powinna zwracać obiekt typu A?

[ A a; a = foo(); ] to jest generalnie to samo co [ A a2 = foo(); ] tzn. przypisanie wartości funkcji zwracanej przez foo() do obiektów a i a2, tylko że ta funkcja nic nie zwraca?

0

A co to za kompilator? MSVC++ nie przepuści czegoś takiego.

0
byku_guzio napisał(a)

A co to za kompilator? MSVC++ nie przepuści czegoś takiego.

rozumiem że zwraca błąd przy funkcji (że brakuje return).
kompilator code::blocks .

0

1>f:\test.cpp(24): error C4716: 'foo' : must return a value

W MSVC++ nie da się skompilować.

A foo () { /* ... */ };

funkcja foo, która zwraca obiekt klasy A

A a;
a = foo();
A a2 = foo();

Tak to jest to samo co:

A a = foo();
A a2 = foo();

Jakby całość wyglądała tak:

 class A { /* ... */ };
A foo () { A c; return c; };
 
int main()
{
     A a;
     a = foo();
 
     A a2 = foo();
 
    return 0;
}

To już okej:P

U mnie w C::B daje Build Messages w GCC:
F:\cplus\CODE\test\main.cpp||In function 'A foo()':|
F:\cplus\CODE\test\main.cpp|6|warning: no return statement in function returning non-void|
== Build finished: 0 errors, 1 warnings ===

Ale puszcza to dalej i śmiga.

0

Specyfikacja mówi, że Flowing off the end of a function is equivalent to a return with no value; this results in undefined behavior in a value-returning function.
GCC powinien chociaż warningiem sypnąć.

W skrócie: nie powinno się tak robić, bo może wybuchnąć.

1
oczekp napisał(a)
A a;
a = foo();
A a2 = foo();

Tak to jest to samo co:

A a = foo();
A a2 = foo();

Nie, to nie jest to samo.

A a = foo(); //do akcji wkracza konstruktor
A a2;
a2 = foo(); //do akcji rusza operator przypisania
0

byku_guzio faktycznie.
Czegoś nie łapie. Mając ten kod i zakładając,że kompilator to puszcza tak jak w C::B

class A { /* ... */ };
A foo () { /* ... */ };
 
int main()
{
     A a; //uruchomi się konstruktor
     a = foo(); //przypisanie
 
     A a2 = foo();//tu nie uruchomi się kontruktor
 
    return 0;
}

To konstruktor się uruchomi chyba tylko raz. Bynajmniej tak mi wychodzi podczas debugowania.

1

Zgadza się, ale co do tego ostatniego nie możesz być pewien co się stanie. Ponieważ jeżeli funkcja nie zwraca wartości, a nie jest void to mamy do czynienia z undefined behavior. Wszystko zależy od implementacji kompilatora - może np.wystrzelić rakiety z głowicami nuklearnymi w Twój komputer ;).
Jeżeli foo będzie wyglądać tak:

A foo()
{
    A a;
    a.b = 10; //załóżmy, że klasa a ma pole b typu int
    return A;
}

to przy

A a2 = foo();

wywoła się tylko konstruktor i to tylko raz i a2.b będzie równe 10

C++ być trudna i poryta język :D - za to go lubię ;) Nie można olewać warrningów. Na szczęście MSVC++ rzuca takowym jak nie wszystkie ścieżki zwracają wartość z funkcji

0

No to teraz wszystko jasne i piękne:)
Dzięki.
Heh:)

może np.wystrzelić rakiety z głowicami nuklearnymi w Twój komputer ;).

  • na szczęście był zbyt leniwy ^^
1

Jeszcze trzeba pamiętać o jednym - w momencie, gdy w funkcji zwracamy obiekt, a nie wskaźnik na niego - wywoła się nam jeszcze konstruktor kopiujący.
Także przy A a2 = foo(); wywoła nam się konstruktor przy tworzeniu obiektu w funkcji i przy wyjściu konstruktor kopiujący dla nowego obiektu a2.

0

Rev: Niekoniecznie.

0

No tak, faktycznie, przy włączonych optymalizacjach w tym przypadku kompilator VC++ ominie kopiowanie.

1 użytkowników online, w tym zalogowanych: 0, gości: 1