How to resolve variable conflicts in header files? - c++

I am writing an adaptive step size update algorithm in OpenSees (an opensource earthquake engineering simulation project written majorly in visual studio c++). I am facing a conflict between two variables having the same name in two different header files (namely, windef.h and steelz01.h). I need a way to resolve this conflict.
I am using gnuplot-iostream.h in my project, I am facing this conflict only when I include this header file, otherwise there is no conlfict, code is builidng perfectly.
Basically gnuplot-iostream.h is calling windows.h, which is further calling windef.h. I have added include gauards in steelz01.h file, but it did not resolve the issue.
When I change the varaibale name in steelz01.h to a different name, then also the code is perfectly building. No ISSUE found. But, I don't want to channge the name of the variable in steelz01, it has serious repercussions.
I am including header files like this
#include "gnuplot-iostream.h"
#include <SteelZ01.h>
This is how the variable SIZE is defined in steelz01
#define LOOP_NUM_LIMIT 30
const int SIZE = LOOP_NUM_LIMIT; //limit of array number
and in windef.h, it is defined like this
typedef struct tagSIZE
{
LONG cx;
LONG cy;
} SIZE, *PSIZE, *LPSIZE;
typedef SIZE SIZEL;
typedef SIZE *PSIZEL, *LPSIZEL;
Visual Studio 2017 is throwing this error,
1>c:\program files (x86)\windows kits\8.1\include\shared\windef.h(190): error C2378: 'SIZE': redefinition; symbol cannot be overloaded with a typedef
1>e:\phd working folder\0_ops_github\src\material\nd\reinforcedconcreteplanestress\steelz01.h(17): note: see declaration of 'SIZE'
I am expecting a way to resolve this conflict and a successful build.

I would suggest you to put include statement in namespace,
namespace ABC
{
#include "gnuplot-iostream.h"
}
namespace PQR
{
#include <SteelZ01.h>
}
Call:
ABC::SIZE
PQR::SIZE
This will not change any code of existing libraries. However, author of library using common names hence suggest him to keep common name under namespace to reduce any conflict.

Related

Referring to an object from custom library gives error: "pointer to incomplete class type is not allowed"

So in my Visual Studio solution I'm making a library and I have two Visual Studio projects, one for the library and one for the sandbox. In the library I'm trying to use forward declarations to create a class. What I'm simply doing in this example is creating a header file for my class, declaring std::string with the following forward declaration and creating a member pointer with that class.
Library project:
ClassFromLibrary.h
#pragma once
namespace std {
class string;
}
class ClassFromLibrary {
public:
ClassFromLibrary();
~ClassFromLibrary();
std::string* forwardDeclaredString;
};
ClassFromLibrary.cpp
#include "ClassFromLibrary.h"
#include <string>
ClassFromLibrary::ClassFromLibrary()
: forwardDeclaredString(new std::string("Hello, world!"))
{
}
ClassFromLibrary::~ClassFromLibrary()
{
}
Sandbox project
main.cpp
#include <Library/ClassFromLibrary.h>
#include <iostream>
int main()
{
ClassFromLibrary test;
std::cout <<
*test.forwardDeclaredString //Root of the problem
<< std::endl;
std::cin.get();
}
The problem
As I said earlier, the library project compiles perfectly. However, the error which I mentioned in the title shows up when the forward declared member variable is referenced in any file from the sandbox project. I have a larger project where I get the same error, and the reason I want to achieve this is because I am using other external libraries within my library project, and when I create applications with it I don't want to have to put all the library include directories in the project properties, only the one for my library.
Thanks in advance!
You know that putting names in namespace std makes program ill-formed (except for some cases?)? Well, know you know why. The bug you have is a symptom of undefined behavior.
In my test, the way you declared your forward declaration in std is not how it is actually declared in string header. Yet it's a same name, so now you have name conflict (you have it as soon as you include iostream, which includes string. This is what my compiler is telling me when I am try compile your code:
/opt/compiler-explorer/gcc-8.2.0/lib/gcc/x86_64-linux-gnu/8.2.0/../../../../include/c++/8.2.0/bits/basic_string.h:6628:17:
error: reference to 'string' is ambiguous
struct hash<string>
This is different from the error you put in the question, but since the behavior is undefined, anything can happen.

'byte' : ambiguous symbol error when using of Crypto++ and Windows SDK

In Visual Studio 2012, I'm trying to encrypt a file with Crypto++ library with AES encryption and CBC mode as following :
#include <Windows.h>
#include "aes.h"
#include "modes.h"
#include "files.h"
#include <Shlwapi.h>
using namespace CryptoPP;
INT main(INT argc, CHAR *argv[])
{
CHAR szKey[16] = {0};
CHAR szInitVector[AES::DEFAULT_KEYLENGTH] = {0};
StrCpyA(szKey, "qqwweeff88lliioo");
StrCpyA(szInitVector, "eerrttooppkkllhh");
CBC_Mode<AES>::Encryption encryptor((byte*)szKey, AES::DEFAULT_KEYLENGTH, (byte*)szInitVector);
FileSource fs("in.txt", true, new StreamTransformationFilter(encryptor, new FileSink("out.aes")));
return 0;
}
In Qt it does work!, But here I wondered why got the following error :
error C2872: 'byte' : ambiguous symbol
could be 'c:\program files (x86)\windows kits\8.0\include\shared\rpcndr.h(164) : unsigned char byte'
or 'z:\cryptography\app_aesencryption\aes headers\config.h(237) : CryptoPP::byte'
Due to prevent of ambiguous symbol error, even I cast bellow statement with CryptoPP::byte* :
CBC_Mode<AES>::Encryption encryptor((CryptoPP::byte*)szKey, AES::DEFAULT_KEYLENGTH, (CryptoPP::byte*)szInitVector);
I didn't get any error for 'byte' : ambiguous symbol, But It give me many errors as :
error LNK 2038
By the way, I linked .lib file of Crypto++, So I think this error is Unlikely for this.
Is last error related to CryptoPP::byte*? Is there any solution?
'byte' : ambiguous symbol error when using of Crypto++
We had to move byte from global namespace to CryptoPP namespace due to C++17 and std::byte. The change occurred at Commit 00f9818b5d8e, which was part of the Crypto++ 6.0 release.
Crypto++ used to put byte in the global namespace for compatibility with Microsoft SDKs. Without the global byte then you would encounter 'byte' : ambiguous symbol error again.
The error you are seeing is because you used using namespace CryptoPP; and the Microsoft kits still put a byte in the global namespace. The error did not surface under Qt because Qt does not put a byte in the global namespace.
There are several work-arounds discussed at std::byte on the Crypto++ wiki.
Incidentally, Microsoft kit code will break when it encounters a C++17 compiler and std::byte because of Microsoft's global byte. You will encounter the same error when using the Windows kits. Ironically, Microsoft employees authored C++ std::byte. Also see PR0298R0, A byte type definition.
The first problem solved with changing byte* to CryptoPP::byte* :
CBC_Mode<AES>::Encryption encryptor((CryptoPP::byte*)szKey, AES::DEFAULT_KEYLENGTH, (CryptoPP::byte*)szInitVector);
But to solving the second problem (error LNK 2038) :
This is related to link error, Every body that using of crypto++ in Visual Studio may have this problem.
First I was download library from bellow link for visual studio in which containt .sln (VS Solution) :
https://www.cryptopp.com/#download
I build the library via Batch Build as cryptlib project in both state (Debug|Win32 and Release|Win32)
Because I used of Debug mode, I linked cryptlib.lib in cryptopp700\Win32\Output\Debug in dependencies section.
Also add dependencies for header files...
But I forgot something in project properties :
Finally, I set Runtime Library option to Multi-threaded Debug (/MTd)
This option is in :
Project Properties
Configuration Properties
C/C++
Code Generation
Runtime Library
I know this answer is not directly relating to Crypto++ & Windows SDK, but I know I found this while trying to figure out the same error when using the Nodejs addon library called Nan instead. I'm putting this answer here because it's in an accessible place for others who might run into similar issues to me.
I hadn't had too many issues compiling the project for a while but then ran into the same error as mentioned above. I wasn't using a byte symbol anywhere. There were dozens of errors pointing to libraries in the Windows SDK which also was conflicting with the cstddef header as the error addresses.
What I was able to do to fix the problem was rearranging the headers so that the Nan-related content (and any of my own header files that references it) was on top, above even the other standard C/C++ libraries. After that was done, the errors went away.
The decision is simpliest. Delete from your code 'using namespace std' and use namespace std:: before every operation instead.

PIN with python includes tool. Ambiguous symbol

I'm having the same problem than this post.
Basically I am trying to compile a PIN tool that uses Python.h.
There are some types that are called the same for Windows.h and PIN.h and either of them declared a namespace for them so I'm getting error C2872: 'UINT32' : ambiguous symbol
The problem is that my PIN tool imports PIN.h and Python.h (which imports at the same time Windows.h) and both of them have same name types so the compiler doesn't know what type is each one and i'm getting the ambiguous symbols error
I cant use the solution:
namespace WINDOWS
{
#include <Windows.h>
}
or
namespace PIN
{
#include <PIN.h>
}
Because there are too many reference to them that need to be renamed and that would be a mess (PIN and Windows.h libraries uses UINT32 or CONTEXT a lot of times).
Is there any elegant way to fix this?

Global variables in C++ and CriticalSections

I have several global critical sections that need visibility across 3 or more classes defined in 3 or more .cpp files. They're defined in an h file as:
GlobalCS.h
#pragma once
#include "stdafx.h"
extern CRITICAL_SECTION g_cs1;
extern CRITICAL_SECTION g_cs2;
etc...
In a GlobalCS.cpp they are defined
#include "stdafx.h"
#include "GlobalCS.h"
CRITICAL_SECTION g_cs1;
CRITICAL_SECTION g_cs2;
Then in the cpp for the classes they need to work in they're included as
#include "stdafx.h"
#include "GlobalCS.h"
The linker is complaining giving unresolved external in the files where the critical sections are being used. I didn't expect this since the variables are defined as extern. What am I doing wrong or how do I get around this?
error LNK2001: unresolved external symbol "struct _RTL_CRITICAL_SECTION g_CS_SymbolStrPlotAccess" (?g_CS_SymbolStrPlotAccess##3U_RTL_CRITICAL_SECTION##A)
Not sure why you are getting the error. I tried the same thing in Visual Studio and in _tmain function I wrote the following:
int _tmain(int argc, _TCHAR* argv[])
{
//::g_cs1;
ZeroMemory(&g_cs1, sizeof(::g_cs1));
return 0;
}
And it built with no issues whatsoever.
Thank you all for your help. It always is helpful to have sanity checks. The issue was once again Visual Studio setup. Visual Studio will generate link errors if it doesn't like the way you have files added to your project. This is the second bug I've encountered that generated a link error based on the way the project was configured. If it's that important VS should either prevent you from modifying a project in a harmful way or provide a proper error message.
Anyway, the error is the same as this one:
LNK2019 Error under Visual Studio 2010
I had the GlobalCS.h and GlobalCS.cpp in the source directory. I prefer it this way because I find it makes finding files and code faster and in a large c++ project, just moving around the code base is a significant time waster. So much time could be saved writing c++ code if the IDE was designed to help find code faster. 2012 is A LOT better than 2010 so I'll give MSFT that but there could be a lot more features to that end (afterall VS has been around for almost 2 decades now)these types of persistent problems just get in the way of development. When I moved GlobalCS.h to the Header folder and cleaned the project and rebuilt, everything compiled as expected. The other similar error VS will throw at you is when the .h file is in the code directory (so #includes work) but not in the project. I got the same error messages when that happened and it took a good couple days to figure that one out. In a small project, it might not be as problematic but in big solution with multiple projects and dozens of files, it can be problematic.

getting error for ambiguous symbol and need help to remove it

i am getting this error which i unable to remove in visual studio 2010. i am using one third party library which uses its own definition for "string" Also visual studio's xstring file is there in the folder where it gets installed. now when i am trying to compile code i am getting following error
1>...\xyz.cpp(24): error C2872: 'string' : ambiguous symbol
1> could be 'third party library path\string.h(31)
1> or 'c:\program files (x86)\microsoft visual studio 10.0\vc\include\xstring(2063) : std::string'
compiler is not able to understand which string definition it should use. How can i remove this error in visual studi 2010. I want the code to use third party string definition.
i tried to set third party path in include directory but still i am seeing this error.
Please help me. Thanks in advance
This is an example of a namespace clash. You probably have in your code:
#include <3rdPartyString.h> // declaration of 3rd party string type
#include <string> // declaration of std::string
using namespace 3rdPartyNamespace;
using namespace std;
...
string myStr; // which string type?
Compiler now doesn't know which string you want to use - one from 3rd party library or STL one. You can resolve this ambiguity by prepending namespace name to the type:
3rdPartyNamespace::string myStr; // if you want to use string from 3rd party library
or
std::string myStr; // if you want to use STL string
Never place using namespace namespace_name; in headers but try to avoid it in source files as well. The best practice is to prepend type name as this does doesn't pollute your current namespace with the other one thus avoiding namespace clashes.
Namespaces were invented to prevent these ambiguities. Make sure you never use using namespace std (that specific using namespace is bad practice anyway, and "std::" isn't that long to type) and it should be fine, just use std::string if you want the standard string.
// Without "using namespace std;"
string foo; // string from third party library used.
std::string bar; // string from standard library used.
The two definitions of string are clashing with each other so the compiler doesn't know what to use so you need a way to differentiate the two and that's where namespaces come in.
You can use the namespace that your third party string uses when referring to that string as the errors you are showing implies you have using namespace std in your code.
I ran into this issue recently by adding a Class Library project to a very large solution that included an in-house String library, the using namespace System; in the pre-generated header was causing the ambiguity.
There is System.String. If not intended to use, make sure to indicate otherwise. Example System::String, or Custom::String