0

So I had this dll where I was using two typedefs wrapped in a namespace like so,

Constants.h

namespace constants
{
    typedef int Integer;
    typedef float Decimal;
}

Now the place where I was using it in the dll, I used the namespace without using the fully qualified name like using namespace constants.

Now there was a file handler.h which was importing another utility.h which in turn was importing this constants .h

utility.h (same dll as constants.h)

#include "constants.h"
using namespace constants;

handler.h (another dll)

#include "utility.h"
#include "common.h"

The common.h here has the same Integer and Decimal typedefs defined for another data type.

As far as I know when we use using namespace constants the typedefs scope will only be inside that translational unit, i.e here utility.h.

Hence typedefs defined in common.h was not messing up with constants typedef present in utility.h, since they were wrapped under namespace.

common.h (third dll)

typedef unsigned long int Integer

This was working fine in visual studio and the binaries were built successfully.

However on Linux I was getting

 error: reference to 'Integer' is ambiguous

Why the same code is giving compiler error in Linux but not windows.

I was using Microsoft visual studio 2017,

Note : I know about the fact that we should always use namespace with fully qualifier name. But I just want to know why behaviour is different in win/unix.

Himanshu Poddar
  • 7,112
  • 10
  • 47
  • 93
  • 3
    `using namespace ...` in a header is usually a bad idea. There is no difference between Win and Linux. Can you create a [mcve] ? – 463035818_is_not_an_ai May 21 '21 at 04:51
  • The Visual Studio compiler has been known to be somewhat lax with standards before. Other than that, is the file (source and header) structure *exactly* the same for both targets? Are all `#include` directives *exactly* the same? – Some programmer dude May 21 '21 at 04:56
  • 4
    It sounds like you’re confused about what a “translation unit” is. If a header file is included by two source files, its code becomes part of both translation units. – Sneftel May 21 '21 at 04:56
  • @Sneftel so do you mean, that if utility.h is included in any other cpp file, the scope of namseapce constants extends to that file too? If that is soI should have definitely got compiler error on windows – Himanshu Poddar May 21 '21 at 04:58
  • @Someprogrammerdude yes exactly same – Himanshu Poddar May 21 '21 at 05:01
  • 1
    I’m not sure what you mean by “namespace constants”. But a file-scope `using namespace` directive from a header will affect the rest of the source file, yes. – Sneftel May 21 '21 at 05:02
  • 1
    I guarantee you, there is no difference between compilers/platforms here. It sounds like you’re conflating various concepts (DLLs in particular) and not recognizing where your source changes are causing the difference. Try to put together a MCVE. – Sneftel May 21 '21 at 05:03
  • 1
    To expand on the comment by @Sneftel regarding [translation units](https://en.wikipedia.org/wiki/Translation_unit_(programming)), it's basically that the compiler doesn't know about "source files" or "header files". All it really know about is the current translation unit (basically a single source file with all included header file). It doesn't know anything about other possible translation units. It's the *linkers* job to put the different compiled translation units (by now object files generated by the compiler) together into a single executable. – Some programmer dude May 21 '21 at 05:05
  • Since you are asking about why different compilers handle (possibly) ambiguous code in different ways, I guess the following is a reference (for the misinformation in your question), rather than a duplicate: [What is a “translation unit” in C++?](https://stackoverflow.com/questions/1106149/what-is-a-translation-unit-in-c) – JaMiT May 21 '21 at 05:29
  • @largest_prime_is_463035818 off topic: But how exactly is largest prime 463035818 or is it just for pun? – Himanshu Poddar May 21 '21 at 05:44

1 Answers1

1

As far as I know when we use using namespace constants the typedefs scope will only be inside that translational unit, i.e here utility.h.

utility.h is not a "translational unit" by itself. If you include utility.h into another file, then that other file (with all its included files) is a translation unit.

For example, after the pre-processor has handled the include directives, the content of handler.h (within its translation unit), would be:

namespace constants
{
    typedef int Integer;
    typedef float Decimal;
}
using namespace constants;
typedef unsigned long int Integer

And that's potentially a problem, since the unqualified type name Integer would be ambiguous.

Why the same code is giving compiler error in Linux

You haven't actually shown how you use Integer, so we cannot confirm. But if the compiler is correct, then you are referring to Integer ambiguously, which makes the program ill-formed.

But the same thing is working fine on visual studio

If the aforementioned assumption about using Integer is correct, and if your compiler doesn't issue a diagnostic message, then the compiler doesn't conform to the C++ standard.

eerorika
  • 232,697
  • 12
  • 197
  • 326