fehlender Compilerfehler/Warnung

Gast #5362549
Lesenswert?
• ▲
▼
Ahoi,

ich habe hier ein interessantes Phänomen mit Visual Studio Express 2013.
Und zwar erzeuge ich eine DLL in C, die in einem Delphiprogramm 
eingebunden wird.
Ich bekomme keine Warnung bzw. keinen Compilerfehler, wenn meine 
Funktion im Header nicht korrekt deklariert ist.
Das Einbinden im Delphicode (dort werden auch Parameter übergeben) 
funktioniert aber einwandfrei.

foo.h
1
#ifdef __cplusplus
2
#define EXPORT extern "C" __declspec (dllexport)
3
#else
4
#define EXPORT __declspec (dllexport)
5
#endif;
6

7

8
EXPORT char* bar();

foo.c
1
#include "foo.h"
2

3
char* bar(bool var1, int var2, char* var3, double* var4){
4
do_something();
5
};

Wie kann das sein?
Gast #5362560
Lesenswert?
• ▲
▼
donvido schrieb:
> wenn meine Funktion im Header nicht korrekt deklariert ist.

Was ist denn deiner Meinung nach falsch? Wenn du bar() schreibst, 
bedeutet das "beliebige Parameter beliebigen Typs". Das ist kompatibel 
zu den angegebenen Parametern. Wenn du wirklich "keine Parameter" haben 
willst, musst du "bar(void)" schreiben.
#5362567
Lesenswert?
• ▲
▼
Ich denke eher, dass der Compiler dir nichts mitteilt, da du diese 
Funktion in diesem Zusammenhang nirgends aufrufst.

Habs mal mit dem VS 2015 getestet.
1
char* bar();
2

3
char* bar(bool var1, int var2, char* var3, double* var4)
4
{
5
    printf("FOO");
6
    return var3;
7
};
8

9
int main()
10
{
11
    char x;
12
    double y;
13

14
    /* geht */
15
    bar(true, 1, &x, &y);
16

17
    /* geht nicht */
18
    bar();
19
}

Beim Aufruf der bar() liefert der Compiler dann:
error LNK2019: Verweis auf nicht aufgelöstes externes Symbol ""char * 
__cdecl bar(void)" (?bar@@YAPADXZ)" in Funktion "_main".

Für den Compiler sind es wohl "überladene Funktionen" wobei er für bar() 
keine Funktionsdefinition finden kann.
Gast #5362572
Lesenswert?
• ▲
▼
Dr. Sommer schrieb:
> donvido schrieb:
>> wenn meine Funktion im Header nicht korrekt deklariert ist.
>
> Was ist denn deiner Meinung nach falsch? Wenn du bar() schreibst,
> bedeutet das "beliebige Parameter beliebigen Typs". Das ist kompatibel
> zu den angegebenen Parametern. Wenn du wirklich "keine Parameter" haben
> willst, musst du "bar(void)" schreiben.

Okay, das mit "beliebige Parameter" war mir nicht ganz bewusst. Mich 
hats nur gewundert, dass das nichtmal in irgend einer Weise markiert 
wurde.
#5362738
Lesenswert?
• ▲
▼
donvido schrieb:
> Das Einbinden im Delphicode (dort werden auch Parameter übergeben)
> funktioniert aber einwandfrei.

64-Bit oder 32-Bit?

In 32-Bit können verschiedene Aufruf-Konventionen zu lästigen Stack 
Überläufen führen. Das merkt man aber oft nur bei sehr vielen Aufrufen 
und kleinem Stack.

In 64-Bit ist das Aufräumen des Stacks einheitlich gelöst, calling 
conventions sind hier IIRC no-ops.
Gast #5362829
Lesenswert?
• ▲
▼
Adam P. schrieb:
> Kann man etwa im VS2013 als C kompilieren?

Ja, über die Dateiendung (siehe Rufus) oder per Flag /Tc.

Der Schwerpunkt liegt auch bei neueren Versionen des MS-Compilers klar 
auf C++.

"The Visual C++ C compiler is generally compatible with the ISO C99 
standard, but not strictly compliant. In most cases, portable C code 
will compile and run as expected. Visual C++ does not support most of 
the changes in ISO C11."

Man kann inzwischen aber wohl auch Clang (Windows, Android, iOS) und GCC 
(Android, Linux - Remote oder über das Linux-Subsystem) in VS verwenden.
Moderator #5363310
Lesenswert?
• ▲
▼
Dr. Sommer schrieb:
> Was ist denn deiner Meinung nach falsch? Wenn du bar() schreibst,
> bedeutet das "beliebige Parameter beliebigen Typs". Das ist kompatibel
> zu den angegebenen Parametern.

Nicht ganz. Ein Funktionsprototyp ist inkompatibel zu einer K&R-
Deklaration, wenn er Argumenttypen enthält, die einer Promotion
unterworfen sind. Dazu zählt auch bool, wenn es über stdbool.h als _Bool
definiert ist. Der Compiler müsste deswegen einen Fehler ausgeben.

Gibt er keinen Fehler aus, kann es daran liegen, dass

- bool nicht mittels stdbool.h als _Bool, sondern durch den Benutzer als
  int oder unsigned int definiert ist,

- das MS-spezifische __dllspec(dllexport) die beiden Deklarationen
  kompatibel macht (mit diesen MS-Erweiterungen kenn ich mich nicht aus)
  oder

- der Compiler einen Bug hat.

Bei folgendem Code

1
#include <stdbool.h>
2

3
char *bar();
4

5
char *bar(bool var1, int var2, char *var3, double *var4) {
6
  return 0;
7
}

sollte der C-Compiler auf jeden Fall meckern.

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.