0

I have a strange problem. I have those files:

lib.h:

#ifndef _LIB_H_
#define _LIB_H_

double fun(int a);

#endif

lib.c:

#include "lib.h"
#include <stdio.h>

#if !defined(MY_FUN) && ((defined(__MINGW32__) || defined(__MINGW64__)) && defined(_X86_))
#define MY_FUN
double fun(int a)
{
    printf("%d\n", a);
}
#endif

main.cpp:

#include "lib.h"

int main(int argc, char **argv)
{
    fun(2);
    return 0;
}

When I run such code on Windows, I have an error: undefined reference to fun. On Linux (Ubuntu) its ok, compiling without errors. When I put everything in one file (on Windows) its ok as well. But I need to have it in separete files. How to make it right? On Windows Im using MinGW with Code::Blocks.

yak
  • 3,770
  • 19
  • 60
  • 111

2 Answers2

3

Code::Blocks probably compiles your .c file as C code, while on linux you're compiling everything as C++ code, e.g. by invoking g++ directly.

You need to tell that the fun function has C linkage, so lib.h should have this:

#ifdef __cplusplus
extern "C" {
#endif

double fun(int a);

#ifdef __cplusplus
}
#endif

You'll naturally also need to double check that at least one of the conditions in your lib.c file are evaluates to true

  #if !defined(MY_FUN) && ((defined(_WIN32) || defined(_WIN64)) && (defined(__MINGW32__) || defined(__MINGW64__)) && defined(_X86_))

(so at least try by removing that whole #if )

nos
  • 223,662
  • 58
  • 417
  • 506
  • Thank you so much, that was it! Just added `extern ...` in my `*.h` file and it worked :) Could you tell me, what exactly does it mean? Or where I can read about this more? – yak Jul 05 '13 at 12:20
  • 1
    @yak see http://stackoverflow.com/questions/1041866/in-c-source-what-is-the-effect-of-extern-c – nos Jul 05 '13 at 12:48
1
  1. I'm not sure you can use logical operators with the preprocessor, it might depend on your toolchain;
  2. The #define MY_FUN and !defined(MY_FUN) are unnecessary, since you won't compile the file twice;
  3. There is probably at least one more file in your project which plays a role with this problem since, as I expected, this code

    #if (defined(_WIN32) || defined(_WIN64)) && (defined(__MINGW32__) || defined(__MINGW64__)) && defined(_X86_) random error!!! #endif

    int main(){ return 0; }

compiles smoothly on

g++ (Ubuntu/Linaro 4.7.3-1ubuntu1) 4.7.3 as well as on gcc (Ubuntu/Linaro 4.7.3-1ubuntu1) 4.7.3

(sorry about the formatting, I didn't manage to make it look good).

Stefano Falasca
  • 8,837
  • 2
  • 18
  • 24
  • I know it compiles on Ubuntu ... but on Windows it doesnt ... When I put everything in one `*.cpp` file on Windows it compiles just fine with Code::Blocks. Any solutions? There are any other files in my project, just those I pasted here ;) – yak Jul 05 '13 at 12:12
  • nope, my point is: on ubuntu your #if clause causes its "content" not to be seen by the compiler (in my example, the line "random error!!!" does not get complained at by the compiler. On Ubuntu, then, if you just try to compile what you posted on the question, it won't compile (due to the lack of the definition of fun. – Stefano Falasca Jul 05 '13 at 12:30
  • Ok I see, thanks:) so I need to add some `if defined` for ubuntu too! Cheers – yak Jul 05 '13 at 12:33
  • I don't see the point of those defines however. Are you sure you need them? – Stefano Falasca Jul 05 '13 at 12:38