Why does this C++ Class code break the compiler? - c++

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.

Related

Visual Studio: How to test (in code / static_assert) if a compiler option is enabled

I would like to check, in the code, if certain options where set at compile time.
Specifically, I have implemented some exception handling and would like to use a static_assert to be sure the /EHa option was set in the Visual Studio compiler. (I am using 2017 and 2019 with C++Latest enabled)
My solution has 54 projects each of which have 4 configs.... Easy to miss one.
Or... I might want the code to be different if the option is not set....
many thanks
As I played with the options, I did find that the compiler is already giving a warning for this : warning C4535: calling _set_se_translator() requires /EHa
I looked to see if that was an attribute or decorator on the function in the VS headers so I could transplant it directly in my code, but could not find anything.
So far, I have thus settled on adding a comment in the code for other developers to see when the warning is given.
// Save & Restore the Structured Exception Handler
// Set our own handler during the call
class Scoped_SE_Translator
{
private:
const _se_translator_function old_SE_translator;
public:
Scoped_SE_Translator() = delete;
Scoped_SE_Translator(_se_translator_function new_SE_translator) noexcept : // NOTE: Compiler option /EHa is required ("Enable C++ Exception" = "Yes with SEH Exceptions")
old_SE_translator{_set_se_translator(new_SE_translator)} { }
~Scoped_SE_Translator() noexcept { _set_se_translator(old_SE_translator); }
};
I also set up project defaults in my existing solution.props file:
<ItemDefinitionGroup>
<ClCompile>
<ExceptionHandling>Async</ExceptionHandling>
<FloatingPointExceptions>true</FloatingPointExceptions>
<TreatSpecificWarningsAsErrors>4535;%(TreatSpecificWarningsAsErrors)</TreatSpecificWarningsAsErrors>
</ClCompile>
</ItemDefinitionGroup>
However, that depends on developers adding a line in new vcxproj files:
<Import Project="$(SolutionDir)SolutionSettings.props" />
I am not sure if there is a more 'forceful' way to ensure new projects have the 'correct' defaults.
I suggest that you could use [Predefined macros(https://learn.microsoft.com/en-us/cpp/preprocessor/predefined-macros?view=msvc-160).
_CPPUNWIND: Defined as 1 if one or more of the /GX (Enable Exception Handling), /clr (Common Language Runtime Compilation), or /EH
(Exception Handling Model) compiler options are set. Otherwise,
undefined.
Also, you could refer to Microsoft Docs about To set this compiler option programmatically.
Besides, you could also use code to determine whether /EHa is enabled. For example:
inline bool CodeHasEHaSwitch()
{
bool dtorCalled = false;
struct CCheckEHaSwitch
{
CCheckEHaSwitch( bool& dtorCalled) : dtorCalled( dtorCalled ) {}
~CCheckEHaSwitch() { dtorCalled = true; }
bool& dtorCalled;
static void Win32ExceptionTranslator( unsigned int nExceptionCode,
EXCEPTION_POINTERS *pExceptionInfo )
{ throw nExceptionCode; }
};
_se_translator_function pfnPrevSeTranslator =
_set_se_translator( CCheckEHaSwitch::Win32ExceptionTranslator );
try
{
CCheckEHaSwitch test( dtorCalled );
*((int*)0) = 0; // generate access violation
}
catch (unsigned int)
{
}
_set_se_translator( pfnPrevSeTranslator );
return dtorCalled;
}

gtest/Google Test C++ build error on Visual Studio 2017

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.

C++/CLI project as static library and different behaviour between VS2013 and VS2015

In an app I'm working on (built with Visual Studio 2015), I have the following structure:
Project A -> Native DLL project. This references project B
Project B -> Native static lib project. This references project C.
Project C -> Static lib project with CLR support turned on.
Project A call a function from Project B, which in turn creates an instance of a class from Project C. The instantiated class has a member which is a wrapper around a managed object.
The problem I'm facing is that when I build the code in Release mode, once the code tries to instantiate the class from Project C, it blows up and says that heap has been corrupted. The place where it blows up seems to be the following function from C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\crt\src\vcruntime\pureMSILcode.cpp
[System::Diagnostics::DebuggerStepThroughAttribute]
_CRT_SECURITYCRITICAL_ATTRIBUTE
int __clrcall _initterm_e (
_PIFV * pfbegin,
_PIFV * pfend
)
{
int ret = 0;
/*
* walk the table of function pointers from the bottom up, until
* the end is encountered. Do not skip the first entry. The initial
* value of pfbegin points to the first valid entry. Do not try to
* execute what pfend points to. Only entries before pfend are valid.
*/
while ( pfbegin < pfend && ret == 0)
{
/*
* if current table entry is non-NULL, call thru it.
*/
if ( *pfbegin != NULL )
ret = (**pfbegin)();
++pfbegin;
}
return ret;
}
Now here is the thing ... If I turn Project C into a DLL (rather than a static lib) everything works fine. What's more interesting is that all this used to work fine when I built the code in Visual Studio 2013. With VS2015, I don't get any heap corruption if I build the code in debug, but it blows up in release.
I'm aware that having CLR support in a static lib is not the best idea, however I can't seem to find any good information about the issues in having CLR support in a static lib. Additionally this was working all fine in VS2013.
I can just change Project C to be a DLL (which makes more sense when having CLR support), however I would like to understand what has caused the current settings to blow up when converting to VS2015.
The following is a close representation of the relevant code from each project:
Project C:
Foo.h
class FooA
{
public:
FooA();
private:
struct FooAImpl;
std::unique_ptr<FooAImpl> _impl;
};
Foo.cpp
struct FooA::FooAImpl
{
gcroot<ManagedFoo^> managedFoo;
FooAImpl(ManagedFoo^ managedFoo_) :
managedFoo(managedFoo_)
{
}
};
FooA::FooA()
{
_impl = std::unique_ptr<FooAImpl>(new FooAImpl(gcnew ManagedFoo()));
}
Project B:
FooB.h
class FooB
{
public:
Result GetResult();
};
FooB.cpp
Result FooB::GetResult()
{
FooA fooA;
Result r = ...;
return r;
}
Project A
FooC.h
class FooC
{
public:
void Bar();
private:
std::unique_ptr<FooB> m_pFooB;
};
FooC.cpp
void FooC::Bar()
{
Result r = m_pFooB->GetResult();
}
Hope someone has some information around what issues may occur in having a static lib with CLR support. Hope the information I provided describes the problem well.

Visual Studio 2010 debugger points to wrong line

The debugger in Visual Studio 2010 is recently pointing at the wrong lines and/or skipping lines and I have no idea why this is. This is a CUDA project and only happens in CUDA files. I've noticed the following:
It always happens at the same part of the program.
The lines it points to are always the same, i.e. not random.
Putting extra code after the culprit lines changes which lines it points to.
It only happens in .cu-files. Moving the code to a .cpp-file does not recreate the problem.
What I have tried:
Clean and rebuilt the solution.
Install SP1 for MSVC10 and do all possible updates via Windows Updates
Set the compiler to not use optimizations in debug mode for both C/C++ and CUDA C/C++
Manually delete all created files and then rebuild from the solution folder.
Deleting the folder C:\Windows\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files
Recreating the solution only using the source files.
Disabling my extensions.
I've managed to reduce the code to the following which might reproduce the problem. Mind that this code has to be inside a .cu-file and most probably needs to be compiled with the cuda compiler for C/C++. Including boost is not really necessary, but this example does show what problems I'm having. A shorter example is at the back.
#include <boost/numeric/ublas/matrix.hpp>
using boost::numeric::ublas::matrix;
struct foo {
foo() : mat(NULL) {}
matrix<float>* mat;
};
bool func(foo *data) {
bool status; // <- skipped line
status = false;
if (status) {
std::cout << "test\n";
return (status); // <- error reported here
}
int size = data->mat->size1(); // instead of here
return status;
}
int main(int args, char* argv[]) {
func(NULL); // force error by passing NULL pointer
return 0;
}
Does anyone have any idea how to solve this or how this could be happening? It's pretty annoying having to debug this way.
Shorter example only showing the skipping lines. No external libraries necessary.
bool func() {
bool status; // <- skipped line
status = false;
return status;
}
int main(int args, char* argv[]) {
func();
return 0;
}
Since the program only contains CPU instructions and variable declarations of types that have no construction contain no instructions, the debugger will not stop there. It just executes instructions and then uses the debugging information that the compiler provided to find the relevant line of source code.

GDB does not break on some lines of code when using multiple source files

I have a program that I'd like to debug by setting a breakpoint in a non-default constructor, but the breakpoint I set is never hit. Below is an example program where this problem comes up. There is no problem hitting breakpoints set in the main function, but any breakpoints set in the Domain.cpp file are ignored:
Main.cpp:
#include <iostream>
#include "Domain.h"
int main()
{
Domain y;
std::cout << y.x << std::endl; // <- No problem setting breakpoint here
return 0;
}
Domain.cpp:
#include "Domain.h"
Domain::Domain()
{
x = 4; // <- A breakpoint here is skipped
}
Domain.h:
#ifndef DOMAIN_H_
#define DOMAIN_H_
class Domain
{
public:
int x;
public:
Domain();
};
#endif /* DOMAIN_H_ */
However, the problem does not exist if I put everything into a single file:
Main2.cpp:
#include <iostream>
int main()
{
class Domain
{
public:
int x;
Domain()
{
x = 4; // <- No problem setting breakpoint here now!
};
};
Domain y;
std::cout << y.x << std::endl;
return 0;
}
Why is this the case? How can I change this so that I'm able to set breakpoints when I use multiple files?
I can confirm that the breakpoints aren't working both when I run the debugger manually in a terminal and when I run it through Eclipse CDT, where I get the same error discussed in this question which was apparently never answered:
Why does Eclipse CDT ignore breakpoints?
I am using:
Eclipse Kepler
Mac OSX 10.8.4
gdb 6.3.5 (Apple version)
gcc 4.2.1 with -O0 and -g3 flags
Please be patient with me. I'm still learning the ropes.
You are likely hitting this GDB bug.
This bug has long been fixed, but your version of GDB is very old (and Apple is unlikely to update it).
This is a very interesting anomaly that I would like to explore further, but I suspect it's related to Eclipse's default GCC settings. Many super basic functions like these get optimized out when they hit the compiler. (one time I tried to track a simple for loop, but the viable was removed entirely on GCC's highest optimization settings)