I am trying to build a simple test using gtest on the latest version of Visual Studio 2017. The code is the following:
#include "pch.h"
#include <gtest/gtest.h>
struct BankAccount
{
int balance = 0;
BankAccount()
{
}
explicit BankAccount(const int balance)
: balance{ balance }
{
}
};
TEST(AccountTest, BankAccountStartsEmpty)
{
BankAccount account;
EXPECT_EQ(0, account.balance);
}
int main(int argc, char* argv[])
{
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
And the build error is:
Error C4996 'std::tr1': warning STL4002: The non-Standard std::tr1 namespace and TR1-only machinery are deprecated and will be REMOVED.
You can define _SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING to acknowledge that you have received this warning.
I already tried:
#define _SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING
But it just makes things worse.
I dont know how to fix this error.
UPDATE
I tried adding the define in the preprocessor's definitions and above the includes. Neither works!!
Try going to:
View -> Properties -> C/C++ -> Preprocessor
and Set Preprocessor Definitions as _SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING
Also another solution is to re-enable TR1 by defining _HAS_TR1_NAMESPACE.
However, disabling error is not a good idea. Your warning may be present due to incorrect project setting and you should inform gtest that your compiler version supports
newer C++ versions by setting GTEST_LANG_CXX11 to be 1.
Related
I'm working on a project for my university, here is a class I have made using C++. Having this class completely breaks Visual Studio compiler. Not including this class will run the program perfectly fine. This is my first time using c++ classes, I'm very familiar with Java OOP programming but this doesn't make sense to me.
#include <vector>
#include <string>
using std::string;
using std::vector;
namespace Studentas {
class Studentas {
private:
string vardas_, pavarde_;
float mediana_, vidurkis_, egzaminas_;
vector<int> pazymiai_;
public:
inline string vardas() const { return vardas_; }
inline string pavarde() {
return pavarde_;
}
inline float mediana() {
return mediana_;
}
inline float vidurkis() {
return vidurkis_;
}
inline float egzaminas() {
return egzaminas_;
}
inline vector<int> pazymiai() {
return pazymiai_;
}
inline void pakeistiVarda(string _vardas) {
this->vardas_ = _vardas;
}
inline void pakeistiPavarde(string _pvd) {
this->pavarde_ = _pvd;
}
inline void pakeistiEgzamina(float _egz) {
this->egzaminas_ = _egz;
}
inline void pakeistiMediana(float _med) {
this->mediana_ = _med;
}
inline void pakeistiVidurki(float _vid) {
this->vidurkis_ = _vid;
}
float skaiciuotiMediana();
};
}
These are the errors I get, I don't believe any of them are relevant as there's 13 errors coming from the compiler.
There are instantly a ton of errors, almost like the compiler doesn't like something. But nothing is marked incorrect visually.
Nothing is wrong with your code, it works fine for me. check this out. Try going to Properties -> Linker -> Debugging -> Generate Debug Info Generate Debug Information optimized for sharing and publishing.
Do you build your project before debugging?
If so, you could go to Project properties->Linker -> Debugging, then set the Generate Debug Info to Generate Debug Information (/DEBUG) or Generate Debug Information optimized for sharing and publishing (/DEBUG:FULL).
For more details I suggest you could refer to the Doc:/DEBUG (Generate Debug Info)
When you specify /DEBUG with no additional options, the linker defaults to /DEBUG:FULL for command line and makefile builds, for release builds in the Visual Studio IDE, and for both debug and release builds in Visual Studio 2015 and earlier versions. Beginning in Visual Studio 2017, the build system in the IDE defaults to /DEBUG:FASTLINK when you specify the /DEBUG option for debug builds. Other defaults are unchanged to maintain backward compatibility.
If you are using vs2107 and above, I suggest you should use / DEBUG: FULL.
I am developing a library which lets user set a crucial type alias, or do it through preprocessor directives.
This type alias (or the directive) is undeclared in the library, by design. Thus, when developing my code I get annoying error messages and squiggles for this undeclared type. This could be avoided if I declare a temporary type for it somewhere. However, I do not like the idea of declaring it when I work with the code and then remove it when I publish it. It is also bug prone, since I could easily forget to remove it.
My question is: Can I define preprocessor directives for VS Code's static analysis (IntelliSense? C/C++ Extension)?
That would let me consider the analysis like what a well defined type alias would produce. And avoid annoying error messages/squiggles.
Minimal reproducable example:
Online compiler example
tCore.hpp
#pragma once
#include <string>
// User is responsible of declaring the tCore type
// tCore interface methods
template<typename TCore>
std::string printImpl();
tPrint.hpp
#pragma once
#include <iostream>
class tPrint {
public:
tPrint() = default;
void print() const {
std::cout << printImpl<tCore>() << std::endl; // <-- Static analysis error here!
}
};
tFoo.hpp - tCore candidate
#pragma once
#include <string>
#include "tCore.hpp"
struct tFoo {};
template<>
std::string printImpl<tFoo>() {
return "tFoo";
}
main.cpp
#include <tFoo.hpp>
using tCore = tFoo;
int main() {
tPrint p{};
p.print(); // -> "tFoo"
return 0;
}
I found out it was IntelliSense causing the error through the C/C++ Extension.
I also found an option of adding compiler arguments to IntelliSense, which is exactly what I was looking for.
Either through the UI:
Press
F1 -> > C/C++: Edit Configurations (UI) -> Scroll down to Defines
Or via the JSON :
c_cpp_properties.json configurations has a field defines which holds any compiler arguments.
When I try to compile the following C code on Visual Studio 2017 with default C/C++ settings:
#include <stdio.h>
#include <stdlib.h>
/* function declaration */
/*Line 6*/ int max(int num1, int num2, int num3);
int main() {
/* local variable definition */
int a = 100;
int b = 200;
int c = 400;
int ret;
/* calling a function to get max value */
ret = max(a, b, c);
printf("Max value is : %d\n", ret);
return 0;
}
/* function returning the max between two numbers */
/*Line 25*/ int max(int num1, int num2, int num3) {
/* local variable declaration */
int result;
if (num1 > num2)
result = num1;
else
result = num3;
return result;
}
I get the error(s):
Expected an Identifier: Line(s) 6,25
Expected a ";": Line(s) 25
Intellisense highlights those lines and wont let me run the code. Yet in Codeblocks (Using the default GNU GCC compiler, from mingW) this EXACT code compiles just fine. What is causing this?
Multiple sources have told me that its not due to Codeblocks using GCC compiler
and Visual Studio using "cl" compiler by default.
The same sources have told me that it is also not due to the possibility of each IDE compiling the code using different C standards.
I have named the the file extension as ".c" and I get these errors
If I try to compile the code as c++(or as a ".c++" file it works, but that's not what I want.
I want C.
I would prefer to use Visual Studio over Codeblocks due to its sleek look and menu layout. I also prefer the Visual Studio debugger.
What steps can I take to successfully compile this simple code on Visual Studio 2017?
Microsoft has a notoriously defined max macro. If the macro definition is pulled into your source for whatever reason, token substitution will wreak havoc. The result of that I'd wager is what you are seeing. Mostly because by your own admission, it happens only in Visual Studio.
The solution (and test for it) is fairly simple. One of these should "fix" your code:
Rename max to something else, like my_max.
Before including any headers, add #define NOMINMAX to suppress the definition of the macros in any included MS headers.
Beyond that you are gonna have to tinker with your project settings and see what may be improperly set. This is not a macro that should be automatically added in a simple console project.
I follow the instructions for build xerces in linux
./configure
make
make install
But I'm trying to run the first example from Programming Guide
#include <xercesc/util/PlatformUtils.hpp>
// Other include files, declarations, and non-Xerces-C++ initializations.
using namespace xercesc;
int main(int argc, char* argv[])
{
try {
XMLPlatformUtils::Initialize();
}
catch (const XMLException& toCatch) {
// Do your failure processing here
return 1;
}
// Do your actual work with Xerces-C++ here.
XMLPlatformUtils::Terminate();
// Other terminations and cleanup.
return 0;
}
But I'm getting a few errors:
=== Build: Debug in vasprun_xml (compiler: GNU GCC Compiler) ===
vasprun_xml/main.cpp|22|reference to `xercesc_3_1::XMLUni::fgXercescDefaultLocale' not define
vasprun_xml/main.cpp 22reference to `xercesc_3_1::XMLPlatformUtils::Initialize(char const*, char const*, xercesc_3_1::PanicHandler*, xercesc_3_1::MemoryManager*)' not define
How can I solve this issues?
Anon Mail has reason.
The problem is that Code::Blocks not auto detect system dynamic library.
We need go to
Project->Build Options->Linker Settings
and than add the the name of your library (in our case xerces-c-3.1) without lib prefix. Ok and than build and run without erros.
Is like do
g++ -o main main.cpp /path-to-your-lib/src/.libs/libxerces-c-3.1.so
I've just learned about value-parametrized unit tests in googletest and would like to use them in my project.
I wrote a simple parametrized test.
Header:
#include <gtest/gtest.h>
namespace EnsembleClustering {
class ParametrizedGTest: public testing::TestWithParam<int> {
public:
ParametrizedGTest();
virtual ~ParametrizedGTest();
};
} /* namespace EnsembleClustering */
Source:
#include "ParametrizedGTest.h"
namespace EnsembleClustering {
ParametrizedGTest::ParametrizedGTest() {
// TODO Auto-generated constructor stub
}
ParametrizedGTest::~ParametrizedGTest() {
// TODO Auto-generated destructor stub
}
TEST_P(ParametrizedGTest, testParameter) {
int n = GetParam();
EXPECT_EQ(n, GetParam());
}
INSTANTIATE_TEST_CASE_P(ParametrizedGTestInstance,
ParametrizedGTest,
::testing::Values(100));
} /* namespace EnsembleClustering */
Now, when I run googletest as usual, the program crashes without any output. The gdb stack trace is
EnsembleClustering-D [C/C++ Application]
EnsembleClustering
Thread [1] (Suspended : Signal : EXC_BAD_ACCESS:Could not access memory)
__gnu_debug::_Safe_sequence_base::_M_attach_single() at 0x100528add
__gnu_debug::_Safe_sequence_base::_M_attach() at 0x100528a74
__gnu_debug::_Safe_iterator_base::_M_attach() at 0x100528bfe
__gnu_debug::_Safe_iterator_base::_Safe_iterator_base() at safe_base.h:90 0x1000016e9
__gnu_debug::_Safe_iterator<__gnu_cxx::__normal_iterator<testing::internal::ParameterizedTestCaseInfoBase**, std::__cxx1998::vector<testing::internal::ParameterizedTestCaseInfoBase*, std::allocator<testing::internal::ParameterizedTestCaseInfoBase*> > >, std::__debug::vector<testing::internal::ParameterizedTestCaseInfoBase*, std::allocator<testing::internal::ParameterizedTestCaseInfoBase*> > >::_Safe_iterator() at safe_iterator.h:154 0x100002e9c
std::__debug::vector<testing::internal::ParameterizedTestCaseInfoBase*, std::allocator<testing::internal::ParameterizedTestCaseInfoBase*> >::begin() at vector:207 0x100001fbe
testing::internal::ParameterizedTestCaseRegistry::GetTestCasePatternHolder<EnsembleClustering::ParametrizedGTest>() at gtest-param-util.h:574 0x1000025b0
EnsembleClustering::ParametrizedGTest_testParameter_Test::AddToRegistry() at ParametrizedGTest.cpp:22 0x100001d3f
__static_initialization_and_destruction_0() at ParametrizedGTest.cpp:22 0x100001349
_GLOBAL__sub_I_ParametrizedGTest.cpp() at ParametrizedGTest.cpp:32 0x100001424
<...more frames...>
gdb
Am I doing something wrong or is this a bug in googletest? Can you reproduce this error?
EDIT: I am on Mac OS X 10.8.
From looking at the source code of gtest the only case if there are no parametrized tests available is on Windows using VC7.1 with disabled exceptions:
// We don't support MSVC 7.1 with exceptions disabled now. Therefore
// all the compilers we care about are adequate for supporting
// value-parameterized tests.
#define GTEST_HAS_PARAM_TEST 1
So, you'll need to check how your MinGW was built and probably update it? And can you run the gtest unit tests to see if they execute the typed parameters test?
More information on MinGW:
On their FAQ they report that when using MinGW the following compile option for building gtest is required: PATH/TO/configure CC="gcc -mno-cygwin" CXX="g++ -mno-cygwin".
Complete Example:
#include <gtest/gtest.h>
namespace EnsembleClustering {
class ParametrizedGTest: public testing::TestWithParam<int> {
public:
ParametrizedGTest();
virtual ~ParametrizedGTest();
};
ParametrizedGTest::ParametrizedGTest() {
}
ParametrizedGTest::~ParametrizedGTest() {
}
TEST_P(ParametrizedGTest, testParameter) {
int n = GetParam();
EXPECT_EQ(n, GetParam());
}
INSTANTIATE_TEST_CASE_P(ParametrizedGTestInstance,
ParametrizedGTest,
::testing::Values(100));
} /* namespace EnsembleClustering */
int main(int argc, char* argv[]) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
I compiled this code using the following compiler call on Mac OS X 10.8:
g++ -IGTEST_INCLUDE_DIR -LGTEST_LIB_DIR -lgtest -o tt2 tt2.cpp
Where GTEST_INCLUDE_DIR and GTEST_LIB_DIR are the path where header and library files are stored. When you compile and execute, what happens?
Thanks #ChristianStaudt and #grundprinzip
I would like to point future readers to following link that explains this problem.
http://libcwd.sourceforge.net/reference-manual/group__enable__glibcxx__debug.html
This is a link to the documentation for GLIBCXX_DEBUG flag. It states the following important points.
"Note that this flag changes the sizes and behavior of standard class templates such as std::vector, and therefore you can only link code compiled with debug mode and code compiled without debug mode if no instantiation of a container is passed between the two translation units."
"When to use it
It is a good idea to use this if you suspect problems related to iterators."
Now, if you look at the stack trace posted originally, the crash happens due to vector<testing::internal::ParameterizedTestCaseInfoBase*> as gtest tries to get an iterator on this container, using begin() method.
In my case, gtest lib was compiled without GLICXX_DEBUG flag, but my test code was compiled with this flag. The test code worked like a charm when I compiled without this flag.