0

If I define the function in the main, everything works fine. But if I define the function in another c file, this weir float multiplication problem happens: it gives 0 always.

example1/main.c:

int multiply_by_2(float scalar) {
    printf("result: %f\n", scalar*2);
}

int main()
{
    multiply_by_2(3);
}

example1/CMakeLists.txt

cmake_minimum_required(VERSION 2.6.0)

project(example C)

add_executable(example main.c)

Output:

result: 6.000000

example2/main.c:

 int main()
    {
        multiply_by_2(3);
    }

example2/a.c:

int multiply_by_2(float scalar) {
    printf("result: %f\n", scalar*2);
}

example2/CMakeLists.txt:

cmake_minimum_required(VERSION 2.6.0)

project(example C)

add_executable(example main.c a.c)

Output:

result: 0.000000
Guerlando OCs
  • 1,886
  • 9
  • 61
  • 150

2 Answers2

2
int multiply_by_2(float scalar) {
   printf("result: %f\n", scalar*2);
}

you have an int returning function which does not return any integer. This triggers undefined behavior (once you call that multiply_by_2 function elsewhere). Be scared, very bad things could happen (even outside of that multiply_by_2 function or outside of its caller).

Next time, compile with all warnings and debug info, so with gcc -Wall -Wextra -g if using GCC. Improve your code to get no warnings.

Read also How to debug small programs.

If you use floating point numbers, be very cautious. They are difficult to understand and behave counter-intuitively (e.g. addition is not associative). Read http://floating-point-gui.de/ first.

If you have several translation units (e.g. source files such as a.c and main.c) you should in practice at least have some common header file and #include it in every *.c file. At a first approximation, your header file should declare all your  [global] types and functions. And you'll need to configure your build automation tool (e.g. write your Makefile) to take into account such dependencies: your header file should somehow be mentioned.

Read much more about C programming. See also some C reference site. Read the documentation of every function you are using (e.g. of printf)

You'll learn a lot by studying the source code of existing small free software programs (e.g. on github, gitlab, in a Linux distribution, etc).

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
  • 3
    _you have an int returning function which does not return any integer. This is undefined behavior._ No, this is not undefined behavior. The behavior is undefined when the value of the function call is used by the caller in this case. The code shown in example2 nowhere uses the value of `multiply_by_2()` function call. – H.S. Mar 09 '19 at 02:52
  • @H.S.: Huh. Learn something new every day. [N1570, 5.9.1 Function definitions, item #12](http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf#page=175): "If the `}` that terminates a function is reached, and the value of the function call is used by the caller, the behavior is undefined." – ShadowRanger Mar 13 '19 at 13:37
  • @ShadowRanger Of course and that what I wrote in my comment - _The behavior is undefined when the value of the function call is used by the caller in this case._ In this sentence by "_in this case_", I am referring the case where the function is suppose to return some value but the return statement is missing. – H.S. Mar 13 '19 at 13:53
  • @H.S.: Yeah, I was thanking you for pointing that out and providing the associated reference. I was surprised, and looked it up for myself; figured I'd save others the effort. :-) – ShadowRanger Mar 13 '19 at 14:38
0

The problem was that I should add a declaration of the functions in main.c, even though my compiler wouldn't warne me about it. With the declarations, all bugs are gone

Guerlando OCs
  • 1,886
  • 9
  • 61
  • 150
  • 1
    I suspect turning up your warning level would get a warning output. Undeclared functions are kind of basic. – ShadowRanger Mar 09 '19 at 02:31
  • 2
    Actually, you should have some common header file and include it everywhere. Copy & pasting the same declaration in *several* files is not scalable and should be avoided (unless perhaps your C source files are generated from something else; then the *generator* could duplicate declarations) – Basile Starynkevitch Mar 09 '19 at 03:01