Problem 1540 - Preprocessor definition of "pascal" in G4SIunits.hh alters behaviour of non-Geant code
Summary: Preprocessor definition of "pascal" in G4SIunits.hh alters behaviour of non-G...
Status: RESOLVED WONTFIX
Alias: None
Product: Geant4
Classification: Unclassified
Component: global/management (show other problems)
Version: other
Hardware: All All
: P5 minor
Assignee: Gabriele Cosmo
URL:
Depends on:
Blocks:
 
Reported: 2013-12-13 15:29 CET by Marek Szuba
Modified: 2013-12-13 16:03 CET (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this problem.
Description Marek Szuba 2013-12-13 15:29:53 CET
Hello,

My code depends on both Geant4 and another framework. That framework defines its own units but as all of them are defined in a namespace called "unit", there are generally no conflicts with ones used by Geant. Unfortunately, due to the way the latter defines "pascal" Geant *can* break the other framework in spite of namespace separation. For details, see below.

The problem stems from the fact that as one can see in G4SIunits.hh, Geant4 "pascal" is defined as a preprocessor macro pointing to "hep_pascal". Now, consider the following minimal example:


#include "FrameworkUnits.h"
#include <G4SIunits.hh>

#include <iostream>


int main(void)
{
  std::cout << "The value of unit::pascal is " << unit::pascal << std::endl;
  return 0;
}


where the contents of FrameworkUnits.h are simply


namespace unit {

const double pascal = 123456.;

}


You might already suspect what the problem is: with the #define line from G4SIunits.hh included after the definition of unit::pascal in FrameworkUnits.h, 
the preprocessor happily converts the latter to a definition of unit::hep_pascal... As a result of which, attempting to compile this example will fail with:

exa.cc: In function ‘int main()’:
exa.cc:9:45: error: ‘hep_pascal’ is not a member of ‘unit’
exa.cc:9:45: note: suggested alternative:
In file included from exa.cc:2:0:
/path/to/G4SIunits.hh:214:21: note:   ‘hep_pascal’


One can work around this by reversing the order of #include directives but I wouldn't call it a good thing, as in the end it makes this a hard-to-track-down heisenbug.

I have encountered this bug in geant-4.9.6, that said a quick look at the code suggests it to remain present in 4.10.0 as well.

Suggested fix: do not use #define to alias hep_pascal to pascal,

Let me know if you need any more information on this!

MS
Comment 1 Gabriele Cosmo 2013-12-13 16:03:23 CET
Is there any reason why you should include G4SIunits.hh in your code ?
This header is included inside the Geant4 distribution since its conception and, as explained in the file's banner, it is used in internal tests for checking coherency in the usage of units within the Geant4 code; nowhere it is pulled in by the Geant4 code and it is really not meant to be used in user's code!
Please, adopt <CLHEP/Units/SystemOfUnits.h> instead, where all units are defined within namespace; this would avoid you also shadowing effects of all units symbols being pulled in the global namespace.
The define to hep_pascal is adopted to avoid collisions on systems where 'pascal' is defined as a reserved keyword.