how to implement a template AVAILABLE OUTSIDE of the module !! (??)

This is a discussion on how to implement a template AVAILABLE OUTSIDE of the module !! (??) within the C++ Programming forums, part of the General Programming Boards category; Originally Posted by mynickmynick my definition of EXTERN is nasty and just to avoid multiple declaration and put #include "Recipes.h" ...

  1. #16
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by mynickmynick View Post
    my definition of EXTERN is nasty and just to avoid multiple declaration and put #include "Recipes.h" also in Recipes.cpp

    Code:
    Recipe.h:
    
    #ifndef RECIPES_CPP_
    #define EXTERN extern
    #else
    #define EXTERN 
    #endif
    
    
    EXTERN int LoadRecipe_Par(FILE * RecipeFile, int * BreakAll,int BreakAllAllowed, char * LoadString, char * VarName, int * RecipePar);
    EXTERN int LoadRecipe_Par(FILE * RecipeFile, int * BreakAll,int BreakAllAllowed, char * LoadString, char * VarName, unsigned int * RecipePar);
    EXTERN int LoadRecipe_Par(FILE * RecipeFile, int * BreakAll,int BreakAllAllowed, char * LoadString, char * VarName, float * RecipePar);
    Code:
    Recipes.cpp:
    
    #define RECIPES_CPP_
    
    #include "Recipes.h"
    
    then as above
    But it is perfectly fine to declare:
    Code:
    extern void foo(...);
    
    ... 
    // still the same file
    void foo(...)
    {
    ...
    }
    Are you trying to avoid something you don't need to avoid? ;-)

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  2. #17
    Alessio Stella
    Join Date
    May 2008
    Location
    Italy, Bologna
    Posts
    251
    Quote Originally Posted by matsp View Post
    With very few exceptions, the implementation of templates MUST be done in header files, so that the entire source of the template implementation is available to the compiler when compiling the code using the template.

    --
    Mats

    I apologize for my gnorance. I didn't know it. But this would lead to severe code size increase. I instead want to have only one function implementation for each use (in this case 3 implementations in machine language) while putting the template in the header would lead to potentially 3*n where is the number of inclusions

    I didn't put it in the header, I compiled the code and the compiler accepts it. I still have to run the function to see if it works properly

  3. #18
    Alessio Stella
    Join Date
    May 2008
    Location
    Italy, Bologna
    Posts
    251
    Quote Originally Posted by matsp View Post
    But it is perfectly fine to declare:
    Code:
    extern void foo(...);
    
    ... 
    // still the same file
    void foo(...)
    {
    ...
    }
    Are you trying to avoid something you don't need to avoid? ;-)

    --
    Mats
    thanks I knew it but I still had compiler errors so I changed it
    I will check it better but doing this it didn't work:

    Code:
    File1.h:
    extern int function();
    
    File1.cpp:
    #include "File1.h"
    
    int function2()
    {
    ..
    function();
    }
    
    int function()
    {
        ..
    }
    
    File2.cpp
    #include "File1.h"
    
    int function3()
    {
      function();
    }

  4. #19
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by mynickmynick View Post
    I apologize for my gnorance. I didn't know it. But this would lead to severe code size increase. I instead want to have only one function implementation for each use (in this case 3 implementations in machine language) while putting the template in the header would lead to potentially 3*n where is the number of inclusions
    Ehm, I don't think you understood. You make an extern declaration in your header-file (x.h), then define the function ONCE in a x.cpp, including the SAME x.h just to make sure that the functions match up.

    So, for example:
    Code:
    // x.h:
    extern int funcx(void);
    
    // x.cpp
    #include "x.h"
    
    int funcx(void)
    {
        return 7;
    }
    This will give you ONE funcx, which is called from wherever it is needed.

    In your case, the template function is only needed inside the recipe.cpp, right? Because the functions using the templated functions are all in recipe.cpp.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  5. #20
    Alessio Stella
    Join Date
    May 2008
    Location
    Italy, Bologna
    Posts
    251
    Quote Originally Posted by matsp View Post
    Ehm, I don't think you understood. You make an extern declaration in your header-file (x.h), then define the function ONCE in a x.cpp, including the SAME x.h just to make sure that the functions match up.


    This will give you ONE funcx, which is called from wherever it is needed.

    In your case, the template function is only needed inside the recipe.cpp, right? Because the functions using the templated functions are all in recipe.cpp.

    --
    Mats
    No excuse me now the thread has separated in two different discussions. the original discussion is about a template used by different modules. In that case I put the implemenation inside Recipes.cpp but i use it also elsewhere. This discussion is up to point #17
    The second discussion from #18 is only about elementary C syntax. I had to use the macro EXTERN (with or without templates in several examples) cause otherwise I had compile time errors. If you like I can do it again and tell you the errors I got. The alternative structures that worked are:
    (1)
    Code:
    File1.h 
    
    extern int func();
    
    File1.cpp
    int func();
    ..
    ..
    func();
    ..
    int func()
    {
    ..
    }
    
    File2.cpp
    
    #include "File1.h"
    
    ...
       func();
    ...
    (2)
    Code:
    File1.h 
    #ifndef FILE1_CPP_
    #define EXTERN extern
    #else
    #define EXTERN 
    #endif
    EXTERN int func();
    
    File1.cpp
    #define FILE1_CPP_
    #include "File1.h"
    ..
    ..
    func();
    ..
    int func()
    {
    ..
    }
    
    File2.cpp
    #define FILE2_CPP_
    #include "File1.h"
    
    ...
       func();
    ...
    I prefer (2) cause I have only one declaration for each function

    While the following did not work:
    (3)
    Code:
    File1.h 
    
    extern int func();
    
    File1.cpp
    #include "File1.h"
    ..
    ..
    func();
    ..
    int func()
    {
    ..
    }
    
    File2.cpp
    
    #include "File1.h"
    
    ...
       func();
    ...
    Last edited by mynickmynick; 08-21-2008 at 05:51 AM.

  6. #21
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,643
    There is no reason to ever do (2) and there is nothing wrong with (3). Post your errors and we'll explain them.

    gg

  7. #22
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Just to confirm codeplugs statement:
    Code:
    #include <iostream>
    
    extern int func();
    
    int func();
    
    
    int main()
    {
      std::cout << func() << std::endl;
    }
    
    int func()
    {
      return 7;
    }
    This compiles fine with
    Code:
    g++ -Wall -ansi -pedantic -Wextra a.cpp
    And before you say "but it's not using any include" I'll ensure you that #include makes absolutely no difference to the compiler itself - all the preprocessor does it merge all the included content into one large file - I did that manually by putting the extern and prototype declarations in the file [because I already have 100s of little test-files in my temp-work directory, and it's hard enough to track what contains somewhat useful code and what doesn't without having to figure out which .h file belongs to which source].

    One possible scenario is of course that some type that you declare is changing between one source and another [perhaps due to different include files or different order of includes].

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  8. #23
    Alessio Stella
    Join Date
    May 2008
    Location
    Italy, Bologna
    Posts
    251
    Quote Originally Posted by Codeplug View Post
    There is no reason to ever do (2) and there is nothing wrong with (3). Post your errors and we'll explain them.

    gg
    i made a test and you are definitely right

    i substituted some of the EXTERN with extern in a couple of header files and the compilation was still succesful
    But believe me i had errors in an older version of this program I am working on and i solved it in that nasty way
    Probably there was something else wrong which had this side effect
    I will start desabling some (or probably all of
    Code:
    #ifndef xx_CPP_
    #define EXTERN extern
    #else
    #define EXTERN 
    #endif
    with

    Code:
    #define EXTERN extern
    and let you know if some errors arise (due to something else wrong)

  9. #24
    Alessio Stella
    Join Date
    May 2008
    Location
    Italy, Bologna
    Posts
    251
    I got it.
    The problem is not with functions. the problem is with variables. (Sorry I forgot that!)
    So this (nasty) works (with some warnings "EXTERN redefined")
    (1)
    Code:
    Camera.h:
    #ifndef CAMERA_CPP_
    #define EXTERN extern
    #else
    #define EXTERN 
    #endif
    ..
    EXTERN Type_CameraArgs 		CameraArgs[MAX_STATIONS_NUMBER][MAX_NUMBER_OF_CAMERAS_PER_STATION];
    ..
    EXTERN void *CameraThreadFunction(void *pContext);
    
    
    
    
    Camera.cpp
    #include "Camera.h"
    void *CameraThreadFunction(void *pContext)
    {
    ..
    }
    
    Station.cpp
    #include "Camera.h"
    
    ..
    CameraArgs..
    CameraThreadFunction();
    
    ..
    if i substitute EXTERN with extern in front of CameraArgs I have this error:

    Station.cpp : undefined reference to CameraArgs

    The reason for this nasty code is that I hate to declare things more than once
    Do you think it has important drawbacks (except for the "EXTERN redefined" warning)?

  10. #25
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Yes, in the case of variables, that's true - you have to declare the variable somewhere - usually in ONE .cpp file.

    You can use the #define trick [actually, extern on functions make no difference - so you could just REMOVE all the EXTERN on funcitons].

    However, it's not a particularly great idea to have a global variable - perhaps you should have an interface to get the cameraargs out of the camera.cpp file instead.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  11. #26
    Alessio Stella
    Join Date
    May 2008
    Location
    Italy, Bologna
    Posts
    251
    Quote Originally Posted by matsp View Post

    However, it's not a particularly great idea to have a global variable - perhaps you should have an interface to get the cameraargs out of the camera.cpp file instead.

    --
    Mats
    ok
    yeah well I have a medium experience with C and a lttle knowledge of C++
    what you're telling me is C++ philosophy
    I will see (matter of time)
    In any case accessing a variable via a function makes the code slower
    thank you

  12. #27
    Alessio Stella
    Join Date
    May 2008
    Location
    Italy, Bologna
    Posts
    251
    Quote Originally Posted by iMalc View Post
    You're not exporting templates at all, you're just exporting 3 regular functions. What those functions happen to call is irrelevant. I think it's extremely obvious what the downsides or limitations of this approach are.

    What's your definition of EXTERN? If those functions were extern "C" exported then I'd think you'd have problems, due to name clashes.
    no i didn't define it extern "C"
    for this discussion let's say i defined it
    #define EXTERN extern

    (even if actually i had defined it
    Code:
    #ifndef RECIPES_CPP_
    #define EXTERN extern
    #else
    #define EXTERN 
    #endif
    but that's out of the scope of this discussion)

  13. #28
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,643
    I would just forget about the #define trick - it just complicates and confuses.

    For function declarations, no need for "extern" - add em if you like.

    For global variables in header files, *always* use "extern" - then define the global in only one source file.

    gg

Page 2 of 2 FirstFirst 12
Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Screwy Linker Error - VC2005
    By Tonto in forum C++ Programming
    Replies: 5
    Last Post: 06-19-2007, 02:39 PM
  2. error: template with C linkage
    By michaels-r in forum C++ Programming
    Replies: 3
    Last Post: 05-17-2006, 08:11 AM
  3. include question
    By Wanted420 in forum C++ Programming
    Replies: 8
    Last Post: 10-17-2003, 03:49 AM
  4. oh me oh my hash maps up the wazoo
    By DarkDays in forum C++ Programming
    Replies: 5
    Last Post: 11-30-2001, 11:54 AM
  5. Function basics
    By sjleonard in forum C++ Programming
    Replies: 15
    Last Post: 11-21-2001, 11:02 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21