1

I have a project in pure C - st usb library and I need to migrate it to c++ and change same structures into classes. I removed all c++ "protections" like:

#ifdef __cplusplus
extern "C" {
#endif

#ifdef __cplusplus
}
#endif

I changed all files extensions from .c to .cpp (except HAL library). I realized that c++ .hex is 7kB smaller then c .hex. When I looked into .map file I saw that many functions are missing. I thought that staticfunctions caused that, but removing static key word didn't help. Does anyone have idea what could cause that some functions weren't compiled. When extensions are .c everything is fine.

too honest for this site
  • 12,050
  • 4
  • 30
  • 52
legier
  • 129
  • 1
  • 9
  • 1
    Just for record: for the compiler and linker, the file extension is irrelevant. – Torbjörn Aug 12 '16 at 08:10
  • A few things that would be interesting to know: 7kB smaller compared to what total size? Did you just lose function definitions, or is the functionality lost in the software? – Eirik M Aug 12 '16 at 08:12
  • 1
    30kB in C, 23kB in C++. I lost functionality. When compiled in c PC does recognize my device, when compiled in c++ it does not. – legier Aug 12 '16 at 08:13
  • 2
    @Torbjörn: Both gcc and MSVC (by default) use the file extension to determine what language the source file is. I am pretty sure the Intel compiler and Clang do the same. Which compiler do you use for which this is *not* the case? – Martin Bonner supports Monica Aug 12 '16 at 08:17
  • 2
    I'm not sure if it is possible to give a better answer than: Something that makes sense in C, but no longer in C++ was not ported correctly. – Eirik M Aug 12 '16 at 08:18
  • C++ linker can remove functions from binary when they are not used or they are used but they were optimized as inline functions. However, it shouldn't have any impact for the way the program works, so I don't think this is the case. – Piotr Siupa Aug 12 '16 at 08:22
  • I use arm-eabi-gcc and arm-eabi-g++ compiler. Can this situation be caused be one of this flags: `-fno-exceptions` `-fno-rtti`? They are for c++ compiler. – legier Aug 12 '16 at 08:29
  • Perhaps this will help: https://en.wikipedia.org/wiki/Compatibility_of_C_and_C%2B%2B – Piotr Siupa Aug 12 '16 at 08:33
  • @legier: Those options won't affect anything you have at the moment. Your C code won't be throwing exceptions or using rtti. – Martin Bonner supports Monica Aug 12 '16 at 08:43
  • Rather than trying to mess with ST's code, you should consider leaving their code as straight C and wrapping it in your own C++ classes to provide a C++ interface to their C library. – rjp Aug 12 '16 at 12:25
  • Those "protections" are not *protection* they are to allow interoperabillity of C code with C++. The safe thing to do with ST's USB library is to compile it as intended as C code and link it with your C++ code. If you want a C++ interface, build a wrapper - rewriting third-party procedural code to be OO is almost pointless and in the case of ST's structurally complex USB code probably impractical. – Clifford Aug 12 '16 at 19:04
  • In some tool-chains the linker can remove unused code; a great deal of ST USB stack can be unused in any particular application. – Clifford Aug 12 '16 at 19:06
  • C and C++ ar3e different languages. Just renaming and recompiling is a good way to mess your program up. Either use the C interface of C++ or - better rewrite the code in C++ (using proper OOP en passant). Any way, you have to carefully review the code for problems due to the different semantics and correct them. – too honest for this site Aug 13 '16 at 18:17

2 Answers2

2

I can think of two main reasons:

  1. Inlining. The compiler can decide there is no need to emit the function as a standalone function if all usages can be inlined.
  2. Unused code. The compiler can see that a function isn't used anywhere in your code and decide to eliminate it from the final result.

If the result is to be used as sort of library, that your environment calls specific functions without having an explicit call in your own code, I think the best method is to compile and link your code as a library (probably dynamic lib) and exporting those functions as library interface (visibility in gcc, dllexport in MSVC) will force the compiler/linker to include them in the produced binary even if they don't see why they are needed right now. (Of course, this is a wild guess about your target environment.)

Another option is to turn off the specific compiler/linker optimizations for removing dead code and forcing emitting standalone function instance for inlined functions, but I think it's very indirect approach, have a wider effect and can complicate maintenance later.

Yehezkel B.
  • 1,140
  • 6
  • 10
1

C++ functions are given different signatures than C functions. Since you lost functionality and the code is much smaller, it's likely that a function that requires C linkage is being compiled as C++ and the signature mismatch is preventing proper linking.

A likely place for this to happen is in the interrupt vector table. If the handler function is compiled with C++ linkage, the handler address won't make it into a table that's compiled with C.

Double check the interrupt vectors and make sure that they reference the correct functions. If they are correct, check any other code compiled with C that might reference an external symbol compiled with C++.

D Krueger
  • 2,446
  • 15
  • 12