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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren