| Summary: | Preprocessor definition of "pascal" in G4SIunits.hh alters behaviour of non-Geant code | ||
|---|---|---|---|
| Product: | Geant4 | Reporter: | Marek Szuba <marek.szuba> |
| Component: | global/management | Assignee: | Gabriele Cosmo <Gabriele.Cosmo> |
| Status: | RESOLVED WONTFIX | ||
| Severity: | minor | ||
| Priority: | P5 | ||
| Version: | other | ||
| Hardware: | All | ||
| OS: | All | ||
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. |
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