I'm using the target attribute to generate different function implementations depending on the CPU architecture. If one of the functions throws an exception it doesn't get caught if I compile with gcc, but with clang it works as expected.
If there is only a single implementation of the function it does work for gcc as well.
Is this a bug in gcc?
Example (godbolt):
#include <stdexcept>
#include <iostream>
using namespace std;
__attribute__((target("default")))
void f() {
throw 1;
}
__attribute__((target("sse4.2,bmi")))
void f() {
throw 2;
}
int main()
{
try {
f();
}
catch(... )
{
std::cout << "Caught exception" << std::endl;
}
}
Output of gcc:
terminate called after throwing an instance of 'int'
Output of clang:
Caught exception
I reported this and a GCC developer confirmed it as a bug: link
For now a workaround seems to wrap the function and use the gnu::noipa attribute to disable interprocedural optimizations:
__attribute__((target("default")))
void f() {
throw 1;
}
__attribute__((target("sse4.2")))
void f() {
throw 2;
}
[[gnu::noipa]]
void f1()
{
f();
}
int main()
{
try {
f1();
}
catch(... )
{
return 0;
}
return 1;
}
The bug is now fixed in gcc's master branch and should be released with gcc version 13.
Related
Using compiler explorer with:
#include <iostream>
#include <memory>
struct test
{
test(int i)
{
std::cout << "test::test("<<i<<")\n";
}
~test()
{
std::cout << "~test()\n";
}
};
template<>
void std::destroy_at(test* p)
{
std::cout<<"std::destroy_at<test>\n";
p->~test();
}
int
main ()
{
auto sp = std::make_shared<test>(3);
return 33;
}
Gives the expected output using C++20 with gcc x86-64 or clang x86-64:
Program returned: 33
test::test(3)
std::destroy_at<test>
~test()
But x64 msvc v19.32 gives:
Program returned: 33
test::test(3)
~test()
As if the std::destroy_at has no effect here.
Is this conforming behavior, my misunderstanding or a msvc non conformance or misconfiguration?
Specializing standard library functions is UB since C++20.
Run the the following C++ program twice. Once with the given destructor and once with std::fesetround(value); removed from the destructor. Why do I receive different outputs? Shouldn't destructor be called after function add? I ran both versions on http://cpp.sh/ and Clang++ 6.0, and g++ 7.2.0. For g++, I also included #pragma STDC FENV_ACCESS on in the source code, nothing changed.
#include <iostream>
#include <string>
#include <cfenv>
struct raii_feround {
raii_feround() : value(std::fegetround()) { }
~raii_feround() { std::fesetround(value); }
inline void round_up () const noexcept { std::fesetround(FE_UPWARD ); }
inline void round_down() const noexcept { std::fesetround(FE_DOWNWARD); }
template<typename T>
T add(T fst, T snd) const noexcept { return fst + snd; }
private:
int value; };
float a = 1.1;
float b = 1.2;
float c = 0;
float d = 0;
int main() {
{
raii_feround raii;
raii.round_up();
c = raii.add(a, b);
}
{
raii_feround raii;
raii.round_down();
d = raii.add(a, b);
}
std::cout << c << "\n"; // Output is: 2.3
std::cout << d << "\n"; // Output is: 2.3 or 2.29999
}
Using the floating-point environment facilities requires inserting #pragma STDC FENV_ACCESS on into the source (or ensure that they default to on for the implementation you are using. (Although STDC is a C feature, the C++ standard says that these facilities are imported into C++ by the <cfenv> header.)
Doing so at cpp.sh results in “warning: ignoring #pragma STDC FENV_ACCESS [-Wunknown-pragmas]”.
Therefore, accessing and modifying the floating-point environment is not supported by the compiler at cpp.sh.
All I needed to do was to do std::cout << std::setprecision(30); before calling std::cout in the code (iomanip should be included as well).
I am developing a C++ tool that should run transparent to main program. That is: if user simply links the tool to his program the tool will be activated. For that I need to invoke two functions, function a(), before main() gets control and function b() after main() finishes.
I can easily do the first by declaring a global variable in my program and have it initialize by return code of a(). i.e
int v = a() ;
but I cannot find a way to call b() after main() finishes?
Does any one can think of a way to do this?
The tool runs on windows, but I'd rather not use any OS specific calls.
Thank you, George
Use RAII, with a and b called in constructor/destructor.
class MyObj {
MyObj()
{
a();
};
~MyObj()
{
b();
};
};
Then just have an instance of MyObj outside the scope of main()
MyObj obj;
main()
{
...
}
Some things to note.
This is bog-standard C++ and will work on any platform
You can use this without changing ANY existing source code, simply by having your instance of MyObj in a separate compilation unit.
While it will run before and after main(), any other objects constructed outside main will also run at this time. And you have little control of the order
of your object's construction/destruction, among those others.
SOLUTION IN C:
have a look at atexit:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void bye(void)
{
printf("That was all, folks\n");
}
int main(void)
{
long a;
int i;
a = sysconf(_SC_ATEXIT_MAX);
printf("ATEXIT_MAX = %ld\n", a);
i = atexit(bye);
if (i != 0) {
fprintf(stderr, "cannot set exit function\n");
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}
http://linux.die.net/man/3/atexit
this still implies however that you have access to your main and you can add the atexit call. If you have no access to the main and you cannot add this function call I do not think there is any option.
EDIT:
SOLUTION IN C++:
as sudgested there is a c++ equivalent from std. I simply paste in here an example which i copied from the link available just below the code:
#include <iostream>
#include <cstdlib>
void atexit_handler_1()
{
std::cout << "at exit #1\n";
}
void atexit_handler_2()
{
std::cout << "at exit #2\n";
}
int main()
{
const int result_1 = std::atexit(atexit_handler_1);
const int result_2 = std::atexit(atexit_handler_2);
if ((result_1 != 0) or (result_2 != 0)) {
std::cerr << "Registration failed\n";
return EXIT_FAILURE;
}
std::cout << "returning from main\n";
return EXIT_SUCCESS;
}
http://en.cppreference.com/w/cpp/utility/program/atexit
Isn't any global variable constructed before main and destructed afterward? I made a test struct whose constructor is called before main and the destructor afterward.
#include <iostream>
struct Test
{
Test() { std::cout << "Before main..." << std::endl; }
~Test() { std::cout << "After main..." << std::endl; }
};
Test test;
int main()
{
std::cout << "Returning now..." << std::endl;
return 0;
}
If you're happy to stick with a single compiler and non-standard C/C++, then GCC's __attribute__((constructor)) and __attribute__((destructor)) might be of use:
#include <stdio.h>
void __attribute__((constructor)) ctor()
{
printf("Before main()\n");
}
void __attribute__((destructor)) dtor()
{
printf("After main()\n");
}
int main()
{
printf("main()\n");
return 0;
}
Result:
Before main()
main()
After main()
Alternatively to the destructor, you can use atexit() in a similar manner - in C++, you do not need to have access to main() to register atexit there. You can do that as well it in your a() - for example:
void b(void) {
std::cout << "Exiting.\n";
}
int a(void) {
std::cout << "Starting.\n";
atexit(b);
return 0;
}
// global in your module
int i = a();
That being said, I'd also prefer the global C++ class object, which will call the b() stuff in its destructor.
This C++ code compiles successfully with VS 2012 but crashes at runtime:
#include <iostream>
#include <functional>
void f()
{
std::cout << "f called" << std::endl;
}
int main()
{
auto get_f= []()
{
bool b = true;
return b ? f : f;
};
std::function<void()> filter(get_f()); // crash here!!!
return 0;
}
If we change get_f to this:
auto get_f= []()
{
return f;
};
then program runs without crashes.
Is it a problem with this code or compiler/std library bug?
I have not tested with newer versions of Visual Studio.
It looks to me like a problem with the standard library (or possibly compiler).
With VS 2013, it compiles and runs without a problem. If we add code to invoke the filter that runs as well:
#include <iostream>
#include <functional>
void f()
{
std::cout << "f called" << std::endl;
}
int main()
{
auto get_f= []()
{
bool b = true;
return b ? f : f;
};
std::function<void()> filter(get_f()); // crash here!!!
filter();
return 0;
}
Output: f called
I'm having trouble for a while with error C2712: Cannot use __try in functions that require object unwinding, after narrowing the problem, I was left with a very very simple code, and i can not understand why it causes this error. I am using Visual Studio under windows.
I am compiling with /EHa (I do not use /EHsc)
The reason I use __try/__except and not try/catch is because I want to catch ALL the errors, and do not want the program to crash under any circumstances, including for example division by 0, that try-catch does not catch.
#include <string>
static struct myStruct
{
static std::string foo() {return "abc";}
};
int main ()
{
myStruct::foo();
__try
{ }
__except (true)
{ }
return 0;
}
output:
error C2712: Cannot use __try in functions that require object unwinding
Here is the solution. For more details read Compiler Error C2712
#include <string>
struct myStruct
{
static std::string foo() {return "abc";}
};
void koo()
{
__try
{ }
__except (true)
{ }
}
int main ()
{
myStruct::foo();
koo();
return 0;
}
Extra Note: no need static if no declaration using your struct (myStruct).