Funktion mit Rückgabewert ohne Rückgabe



  • Hallo Community,

    ich komme von der C# Ecke und bin gar nicht gewohnt was in C so alles erlaubt ist.
    Es scheint doch tatsächlich kein Problem zu sein eine Funktion mit einem Rückgabewert zu definieren, die gar keine Rückgabe macht. In diesem Fall ist wohl der Rückgabewert irgendetwas undefiniertes. Der Compiler macht nicht mal eine Warnung (Dev-Cpp). Folgendes lässt sich ohne Tadel kompilieren (bedenklich):

    #include <stdio.h>
    
    char *testfunc() {
    }
    
    int main(int argc, char *argv[]) {
    	char *testval;
    
    	testval = testfunc();
    	printf("value = %d", testval);
    
       return 0;
    }
    


  • Du hast doch einen Rückgabewert: 0



  • EOP schrieb:

    Du hast doch einen Rückgabewert: 0

    aber nicht von testfunc.

    er muss wohl erst warnings einschalten.

    mickrigweich-c warnt per default:

    warning C4477: 'printf' : format string '%d' requires an argument of type 'int', but variadic argument 1 has type 'char *'
    warning C4716: 'testfunc': must return a value



  • cilker schrieb:

    Folgendes lässt sich ohne Tadel kompilieren (bedenklich):

    Naja, es kann ja sein, dass der Rückgabewert anders erzeugt wir als durch ein 'return'-statement, z.b. durch einen assemblercode, der entsprechende register setzt.



  • C# ist eben deutlich besser gegen Dummheiten "abgesichert", damit auch Schüler mal proggen können.
    Bei C kannst zu Zeigern auch einfach eine 0 zuweisen oder einem int eine Adresse und der Compiler macht dann das beste daraus. Ist aber natürlich eher schlecht, wenn man professionell arbeiten möchte. 🙄



  • Spirit of C:

    - Trust the programmer.
    - Don’t prevent the programmer from doing what needs to be done.
    - Keep the language small and simple.
    - Provide only one way to do an operation.
    - Make it fast, even if it is not guaranteed to be portable.



  • Bin jetzt etwas ausgeschlafener als bei meiner ersten Antwort:
    Ich bekomme von VS:

    Error 2 error C4716: 'testfunc' : must return a value m:\visual studio 2005\projects\testing\test\test\test.cpp 100


  • Mod

    int freche_funktion()
    {
      if (programm_hält())
        return 1;
    }
    

    Und nun?



  • Ohne getestet zu haben gibt es wohl:

    Not all paths return a value



  • SeppJ schrieb:

    int freche_funktion()
    {
      if (programm_hält())
        return 1;
    }
    

    Und nun?

    da fehlt noch ein return.



  • SeppJ schrieb:

    int freche_funktion()
    {
      if (programm_hält())
        return 1;
    }
    

    Und nun?

    Error, non-ASCII chars gehen ja wohl voll nicht im quelltext. 🙄



  • Annfengah schrieb:

    SeppJ schrieb:

    int freche_funktion()
    {
      if (programm_hält())
        return 1;
    }
    

    Und nun?

    Error, non-ASCII chars gehen ja wohl voll nicht im quelltext. 🙄

    Kleinigkeiten - das lernt er schon noch. 😉



  • @cilker:
    Über diese Ecke (Java/C# -> C) bin ich auch gestolpert. An der Uni programmierte man noch sehr viel Java und als ich C begann, fragte ich mich, warum der folgende Code einen Stack Overflow verursachte.

    void MyFunction(MyBigMonsterObjekt obj)
    {
      obj->Counter = 1; // auch eine Stolperecke für Leute welche von C nach C# wechseln
    }
    

    Auch wenn sich C# und C in gewissen Punkten ähnlich sehen, sind sie doch zwei völlig verschiedene Sprachen.

    ---

    char *testfunc() {
    	printf("Hallo");
    } 
    
    int main(int argc, char** argv)
    {
    	char *testval;
    
        testval = testfunc();
        printf("value = %d", testval);
    
        return 0;
    }
    

    Unter mingw-gcc 7.1 bekomme ich zwei Warnungen. Zuerst motzt der Compiler über die fehlende return Anweisung in testfunc() und zweites motzt er über den Formatstring im printf(). Aber ich bekomme als Ergebnis value = 5, den Rückgabewert von printf(). Ich würde mich aber nicht darauf verlassen, dass der Compiler immer den Rückgabewert der letzten Anweisung übernimmt.



  • cilker schrieb:

    Es scheint doch tatsächlich kein Problem zu sein eine Funktion mit einem Rückgabewert zu definieren, die gar keine Rückgabe macht.

    Tja, ist eben so. C ist von Profis für Profis entstanden, und die wissen, was sie tun.

    cilker schrieb:

    In diesem Fall ist wohl der Rückgabewert irgendetwas undefiniertes.

    Nicht "irgendetwas undefiniertes" sondern vom Standard explizit als UB benannt.

    cilker schrieb:

    Der Compiler macht nicht mal eine Warnung (Dev-Cpp).

    C ist von Profis für Profis entstanden, und die wissen, was sie tun. In diesem Fall wissen Profis, dass der gcc für alle möglichen Fälle Schalter(Kombinationen) besitzt, mit denen der gcc Warnungen oder sogar Fehler wirft.
    http://ideone.com/nvxvo7

    cilker schrieb:

    Folgendes lässt sich ohne Tadel kompilieren (bedenklich):

    C ist von Profis für Profis entstanden, und die wissen, was sie tun. Und deswegen bietet ein C-Compiler dem Entwickler auch ein Maximum an Freiheiten bei der Codegestaltung an. Es könnte ja sein, dass irgendein C-Profi genau dieses Verhalten benötigt - und eben nicht vom Compiler ausgebremst werden will.



  • Wutz schrieb:

    C ist von Profis für Profis entstanden ...
    ...
    C ist von Profis für Profis entstanden ...
    ...
    C ist von Profis für Profis entstanden ...

    Soll das heißen dass du gern C lernen möchtest?


  • Mod

    tztztz... schrieb:

    SeppJ schrieb:

    int freche_funktion()
    {
      if (programm_hält())
        return 1;
    }
    

    Und nun?

    da fehlt noch ein return.

    Wieso? Mein Programm hält doch immer, oder kannst du das Gegenteil beweisen?



  • Deutungsversuch schrieb:

    Soll das heißen dass du gern C lernen möchtest?

    nein das soll heißen, dass man sich entweder mit den spezifikationen auseinandersetzen oder (besser) solchen offensichtlichen spielkram unterlassen sollte.
    wenn man also eine funktion definiert, die nicht den rückgabewert void besitzt, dann sollte man grundsätlich auch einen entsprechenden wert zurückgeben lassen, und wenn man printf eine 1-byte-variable übergibt, dann sollte man auch den formatspezifizierer %hhd übergeben oder eben exlizit casten.



  • Wade1234 schrieb:

    wenn man printf eine 1-byte-variable übergibt, dann sollte man auch den formatspezifizierer %hhd übergeben oder eben exlizit casten.

    Das ist Nonsens bzw. Weitertragen von aufgeschnapptem Halbwissen.
    Bei Funktionen mit variabler Parameterliste (printf...) gilt gemäß Standard die integer promotion, d.h. in printf kommen immer int/unsigned int an, für alle Argumente mit arithmetischem Typ kleiner int.
    Demzufolge ist %hd ebenso wie %hhd nur von formalem Wert, praktisch sind sie Augenwischerei, da immer ein %d/%u äquivalent ist, ebenso wie ein expliziter Cast Unsinn wäre (da die compilerinterne Promotion immer ggü. dem expliziten Cast gewinnt).



  • Außerdem wird da ein Zeiger (char 😉 übergeben, kein einzelnes Zeichen.



  • Aha. Wo wird in

    char c=1;
    printf("%hhd",c);
    

    ein Zeiger übergeben?


Log in to reply