Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 12 of 12

Thread: .cpp files not working as I expect

  1. #1
    Junior Member
    Join Date
    Jun 2019
    Posts
    18

    .cpp files not working as I expect

    Please explain .cpp files.

    I have been working on a large project without .cpp files because I was fine with the longer compilation times and I put most of my forward declarations in a single file at the start (and then a few in a second one later).

    I am considering growing up and using .cpp files, but I am getting loads of errors, probably because I don't properly understand the compilation/linking process.

    Am I right in thinking that all the included .h files are in one compilation unit and each of the .cpp files are in others, with each compilation unit needing all the header files to which it refers included?

    My code is here: https://github.com/StagBeetle/Buttseqs but I expect someone knowledgeable can figure it out without looking at the code. To summarise, I moved the definition of two of my functions from the debug.h into a debug.cpp file, added the includes to header files (each with header guards) that it seemed to need, and now I have many of multiple definition errors.

    Here are the first four errors out of about 50:

    C:\Users\Lynxwave\AppData\Local\Temp\arduino_build _328148\sketch\sequencer.ino.cpp.o: In function `nullIntFunc(int)':
    C:\Users\Lynxwave\AppData\Local\Temp\arduino_build _328148\sketch/forwarddec.h:274: multiple definition of `nullIntFunc(int)'
    C:\Users\Lynxwave\AppData\Local\Temp\arduino_build _328148\sketch\debug.cpp.o:C:\Users\Lynxwave\AppDa ta\Local\Temp\arduino_build_328148\sketch/Utility.h:21: first defined here
    c:/program files (x86)/arduino/hardware/tools/arm/bin/../lib/gcc/arm-none-eabi/5.4.1/../../../../arm-none-eabi/bin/ld.exe: Disabling relaxation: it will not work with multiple definitions

    C:\Users\Lynxwave\AppData\Local\Temp\arduino_build _328148\sketch\sequencer.ino.cpp.o: In function `nullIntFunc(int)':
    C:\Users\Lynxwave\AppData\Local\Temp\arduino_build _328148\sketch/forwarddec.h:274: multiple definition of `modes::encoderAllocator(int, int)'
    C:\Users\Lynxwave\AppData\Local\Temp\arduino_build _328148\sketch\debug.cpp.o:c:\program files (x86)\arduino\hardware\tools\arm\arm-none-eabi\include\c++\5.4.1/functional:1829: first defined here

    C:\Users\Lynxwave\AppData\Local\Temp\arduino_build _328148\sketch\sequencer.ino.cpp.o: In function `nullIntFunc(int)':
    C:\Users\Lynxwave\AppData\Local\Temp\arduino_build _328148\sketch/forwarddec.h:274: multiple definition of `nullFunc()'
    C:\Users\Lynxwave\AppData\Local\Temp\arduino_build _328148\sketch\debug.cpp.o:c:\program files (x86)\arduino\hardware\tools\arm\arm-none-eabi\include\c++\5.4.1/functional:1829: first defined here

    C:\Users\Lynxwave\AppData\Local\Temp\arduino_build _328148\sketch\sequencer.ino.cpp.o: In function `nullIntFunc(int)':
    C:\Users\Lynxwave\AppData\Local\Temp\arduino_build _328148\sketch/forwarddec.h:274: multiple definition of `scheduled::newEvent(scheduled::lOE::listOfEvents, std::function<void ()>, long)'
    C:\Users\Lynxwave\AppData\Local\Temp\arduino_build _328148\sketch\debug.cpp.o:c:\program files (x86)\arduino\hardware\tools\arm\arm-none-eabi\include\c++\5.4.1/functional:1829: first defined here

    Each one starts "In function "nullIntFunc(int)", despite the definition of that function simply being {;}
    Each of them seems to claim the error is in forwarddec.h:274 and each (after the first) says the first definition is in functional:1829

    What is going wrong here? Thanks in advance.

  2. #2
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    12,183
    What is the build environment? An .ino is not apparent in the github tree - is that a library folder independent of the sketch?

    It should follow normal build rules - .cpp files are compiled and needed .h's need #include and prototypes before use.

    In the Arduino IDE the INO is needed to define a sketch - they cheat and look up prototypes in that INO file. Other .cpp files in that sketch folder are compiled using standard tools. Any included library is 'self standing' compiled as a separate unit to be linked later.

    As far as the error the provided text suggests : multiple definition of `nullIntFunc(int)'

    It is like `nullIntFunc(int)' is defined in the INO and also the header :: sketch/forwarddec.h

    Where what appears in the header should just be a prototype if defined in the sketch.

    The github link shows a file like forwarddec2.h - but no sign of what is in :: forwarddec.h

  3. #3
    Junior Member
    Join Date
    Jun 2019
    Posts
    18
    Thanks for the response. The build environmnet is just the Arduino IDE. That library structure is the contents of my sketch folder. I've added those files which I tried to upload in bulk earlier.

    As far as I can see, there is only one nullIntFunc(int) in utility.h.

  4. #4
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    7,411
    As @defragster mentioned, I would have expected to see a file like: ButtSeqs.ino in that folder if this is something to build using Arduino.

    Arduino can build .cpp files and I do it all of the time, But Arduino does expect at least one .ino file in your folder and one of them needs to be the name of your sketch folder (.ino).
    If there are multiple .ino files they are combined together logically into one compile unit. Whereas .cpp files are compiled individually.

    Also .ino files, the build system does some stuff for you like create forward function definitions, and autmatically includes Arduino.h. .cpp files are built as is. So for example if your .cpp files calls something like digitalWrite, than that file needs to include the Arduino.h file.

  5. #5
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    12,183
    Updated github shows : sequencer.ino and forwarddec.h

    But neither of them show anything now for nullIntFunc()?

    Error next refers to :: \sketch\debug.cpp.o:c:\program files (x86)\arduino\hardware\tools\arm\arm-none-eabi\include\c++\5.4.1/functional:1829: first defined here

    Not sure what that comes from?

  6. #6
    Junior Member
    Join Date
    Jun 2019
    Posts
    18
    It's in a folder called sequencer on my computer with a sequencer.ino file, now uploaded. The file that makes things go wrong is debug.cpp.

  7. #7
    Junior Member
    Join Date
    Jun 2019
    Posts
    18
    Defragster, I don't know either. I was hoping somebody else would. The errors don't make any sense to me because the lines in functional and forwarddec.h to which are referenced look like they have nothing to do with the definitions.

  8. #8
    Junior Member
    Join Date
    Jun 2019
    Posts
    18
    Has anyone got any ideas?

  9. #9
    Senior Member
    Join Date
    Jul 2014
    Posts
    2,714
    maybe there is some residual .o files
    force rebuild
    either exit and restart Arduino
    or change a parameter in tools (e.g.F_CPU)
    or delete temp arduino build folder
    Last edited by WMXZ; 07-01-2020 at 02:21 PM.

  10. #10
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    7,411
    Quote Originally Posted by PAAUX4 View Post
    Has anyone got any ideas?
    Lots, but maybe none that will help here

    My problem here is, I have no idea of how you build this? Yes you say Arduino and you uploaded the .ino file. But does this github project actually match the folder that you are trying to build?
    If I try to download your project and open up sequencer.ino it will say it must move that file into a folder named sequencer, so I know it does not match exactly your setup. Maybe all of the files under it do?

    Often times it is easier to just create a zip file of your Arduino project. You can do this under Arduino Tools->Archive Sketch... Although I am not sure how that actually works when you have sub-directories like src...

    But I tried downloading and it would not compile... Figured out I needed USB to be some form of MIDI. Now it errors saying something like Audio does not have a member usb2...

    So again for someone to help, it would be good to know exact steps needed to build it. Things like what version of Arduino and Teensyduino you are using. What external libraries are you using?
    What are your compiler settings (Serial->Midi or is it Midi4 or midi16....).

    But in this case it is unclear to me where these errors are. Is it in the compiling or linking phase?

    My guess is linking?

    Probably the issue for nullIntFunc is there could be lots of them...

    That is you define it in a header file:
    Code:
    #ifndef Utility_h
    #define Utility_h
    
    #include <bitset>	
    #include <vector> 
    #include "scheduled.h"
    //#include "forwarddec.h"
    
    typedef void (*voidvoid) ();
    typedef void (*voidint)  (int);
    typedef void (*voiduint8t)  (uint8_t);
    typedef void (*voidbool) (bool);
    typedef void (*voidu3) (uint8_t, uint8_t, uint8_t);
    
    //Functions:
    typedef const char* (*charpvoid) ();
    typedef int (*intvoid) ();
    typedef bool (*boolvoid) ();
    
    void nullFunc(){;}
    void nullIntFunc(int u){;}
    ...
    So suppose utility.h is now included in 10 .cpp files, this will cause this function to be created 10 times.

    Could probably solve it by having it defined as extern in the header file and put the actual functions in a .cpp file.

    Or maybe you can define the function as static so it is only seen within each compiled unit.

  11. #11
    Junior Member
    Join Date
    Jun 2019
    Posts
    18
    WMXZ,

    Thank you but I think the answer is to do with a lack of extern.

    KurtE,

    Thanks for your support and patience. On my PC the code is all in a folder called sequencer and its USB type is Serial + MIDI + Audio.

    However, the error is in the linking phase and it seems the issue is most likely due to lack of extern, as you say, so either I have to add .cpp files for every .h or continue to not use .cpp files. I think using static would cause problems in my situation.

    Looks like it's solved, but I don't understand why C++ isnt clever enough to figure out that its the same definition appearing twice. Probably because when using C++ properly this error does not occur, but come on Bjarne. Something to consider when you're working on C+++.

    The line numbers and files in the error messages still seem wrong though.

    Thanks for your help.

  12. #12
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    12,183
    Quote Originally Posted by PAAUX4 View Post
    ...
    I don't understand why C++ isnt clever enough to figure out that its the same definition appearing twice. Probably because when using C++ properly this error does not occur
    ...
    c/c++ are cleverly designed to do as told - for better or worse - c++ did incorporate some typical clever stuff that all the cool kids were doing

    proper use of 'extern' is needed to avoid redefinition.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •