I've installed Visual Studio 2013 to try some C++ code to test an idea of classes that mutate themselves into other classes and stuff like that (it's stupid but the idea came in a dream) and it is crashing visual studio's compiler, have no idea why.
Just by compiling it, a crash message with the title "Microsft C++ Optimizer deixou de funcionar" (stopped running in my language)
Code:
class F
{
public:
int f;
F(int f){ this->f = f; }
operator A(){ return A(f); }
operator P(){ return P(f); }
};
class A
{
public:
int a;
A(int a){ this->a = a; }
operator F(){ return F(a); }
operator P(){ return P(a); }
};
class P
{
public:
int p;
P(int p){ this->p = p; }
operator F(){ return F(p); }
operator A(){ return A(p); }
};
void stuff(F f)
{
printf("Val -> %d\n", f.f);
}
void main(int argc, char* argv[])
{
P p(3);
stuff((F)(A)(P)(F)(A)(P)(F)(A)p);
}
Tried to build it with gcc. No crashing, just no building either..
That is never going to work. It's way too late to even bother trying to unravel what you've tried to accomplish. Here's the error messages:
||=== 001-forumQuestion, Release ===|
C:\Users\enhzflep\Documents\code\001-forumQuestion\main.cpp|11|error: expected type-specifier before 'A'|
C:\Users\enhzflep\Documents\code\001-forumQuestion\main.cpp|12|error: expected type-specifier before 'P'|
C:\Users\enhzflep\Documents\code\001-forumQuestion\main.cpp|23|error: expected type-specifier before 'P'|
C:\Users\enhzflep\Documents\code\001-forumQuestion\main.cpp|41|error: '::main' must return 'int'|
C:\Users\enhzflep\Documents\code\001-forumQuestion\main.cpp||In function 'int main(int, char**)':|
C:\Users\enhzflep\Documents\code\001-forumQuestion\main.cpp|44|error: no matching function for call to 'P::P(F)'|
C:\Users\enhzflep\Documents\code\001-forumQuestion\main.cpp|44|note: candidates are:|
C:\Users\enhzflep\Documents\code\001-forumQuestion\main.cpp|31|note: P::P(int)|
C:\Users\enhzflep\Documents\code\001-forumQuestion\main.cpp|31|note: no known conversion for argument 1 from 'F' to 'int'|
C:\Users\enhzflep\Documents\code\001-forumQuestion\main.cpp|26|note: P::P(const P&)|
C:\Users\enhzflep\Documents\code\001-forumQuestion\main.cpp|26|note: no known conversion for argument 1 from 'F' to 'const P&'|
||=== Build finished: 5 errors, 0 warnings (0 minutes, 0 seconds) ===|
Related
The following code compiles with no problems from GCC 4.7.1 up to but not including GCC 11.1:
constexpr int SomeValue = 0;
void test () {
void (SomeValue) ();
}
On GCC 11.x it fails with:
<source>:4:23: error: 'void SomeValue()' redeclared as different kind of entity
4 | void (SomeValue) ();
| ^
<source>:1:15: note: previous declaration 'constexpr const int SomeValue'
1 | constexpr int SomeValue = 0;
| ^~~~~~~~~
But the error "redeclared as different kind of entity" seems strange to me: Ambiguous parsing possibilities aside, the scope is different. Also, these tests all compile on all versions of GCC since 4.7.1 (including 11.x), even though AFAIK each one is redeclaring SomeValue as "a different type of entity":
constexpr int SomeValue = 0;
void test1 () { typedef void (SomeValue) (); }
void test2 () { double SomeValue; }
void test3 () { using SomeValue = char *; }
void test4 () { void (* SomeValue) (); }
void test5 () { struct SomeValue { }; }
void test6 () { enum class SomeValue { }; }
As a relatively less nonsensical example, this code also fails from 11.x on in a similar fashion:
constexpr int SomeValue = 0;
struct SomeClass {
explicit SomeClass (int) { }
void operator () () { }
};
void test () {
SomeClass(SomeValue)();
}
Although in this case it's preceded by a vexing-parse warning that also isn't present before 11.x (the fact that the warning is here but not in the above makes sense, the fact that the warning doesn't appear pre-11.x is the interesting bit):
<source>: In function 'void test()':
<source>:9:25: warning: empty parentheses were disambiguated as a function declaration [-Wvexing-parse]
9 | SomeClass(SomeValue)();
| ^~
<source>: At global scope:
<source>:9:26: error: 'SomeClass SomeValue()' redeclared as different kind of entity
9 | SomeClass(SomeValue)();
| ^
<source>:1:15: note: previous declaration 'constexpr const int SomeValue'
1 | constexpr int SomeValue = 0;
| ^~~~~~~~~
Compiler returned: 1
But wait! There's more!
This code -- which I would have expected to fail on 11.x due to the same parsing ambiguities as above -- compiles just fine on all those versions of GCC (including 11.x):
constexpr int SomeValue = 0;
auto closure = [] (int) {
return [] () { };
};
void test () {
closure(SomeValue)(); // <-- doesn't cause any problems
}
No warnings or anything there.
So... What's going on here? Why is it only a problem for SomeValue to be "redeclared as a different kind of entity" in those specific cases, and only since GCC 11.1, and why doesn't closure(SomeValue)() suffer the same problem as SomeClass(SomeValue)()?
Also what changed? Is GCC correct here? Is it a new bug introduced in GCC 11.x? Or perhaps an old bug that was finally fixed in 11.x? Or not a bug at all and something else changed?
I'm struggling to come up with a consistent explanation.
The difference is that your first snippet declares a function that exists globally; all your other declarations are of local entities.
(Note that even if the declaration were valid, you couldn't call that function, since it can't exist.)
In the last snippet, closure is not a type, so it can't be a declaration.
Here is a toned down version of my use case which compiles fine on gcc 4.9.3 and clang 3.7 but fails on VS 2015 Update 2.
#include <functional>
#include <string>
#include<memory>
namespace A {
using handle = std::function<void(std::string)>;
void func(std::string, handle) {
}
}
class B : public std::enable_shared_from_this<B> {
public:
void func();
};
void B::func()
{
auto && cast = std::static_pointer_cast<B>(shared_from_this());
auto const another_variable = [cast]() -> void
{
A::func("hello", [&cast](std::string){ } );
};
}
int main() {
return 0;
}
Here are the errors that I get
Error(s):
source_file.cpp(23): error C2440: '<function-style-cast>': cannot convert from 'const std::shared_ptr<_Ty>' to 'B::func::<lambda_4a58826445f3685613b078cf10fc9f7e>::()::<lambda_8290a9c207487c2dc2e26a5b929b4850>'
with
[
_Ty=B
]
source_file.cpp(23): note: No constructor could take the source type, or constructor overload resolution was ambiguous
source_file.cpp(23): error C2660: 'A::func': function does not take 1 arguments
Interestingly, it compiles fine on VS 2013 as well. Am I missing something very obvious?
I'm wondering if the following code should be considered valid c++, gcc and clang both choke on it while Microsoft and the embedded compiler (green hills) our project uses seem to parse this without problems. This line of code gives gcc and clang trouble:
foo().Bar<int>();
It appears gcc thinks the < is a less than operator instead of specifying a template argument. If Bar is changed to not be a template function gcc accepts it.
class Test1
{
public:
template<typename U>
static void Bar() {}
};
template<typename T>
class Test2
{
public:
Test2()
{
foo().Bar<int>();
}
Test1 foo() { return t; }
Test1 t;
};
int main()
{
Test2<int> t;
}
From my research calling a static member function on an object instance is valid c++. So what are you thoughts? Here is gcc's error:
Error.cpp: In constructor ‘Test2<T>::Test2()’:
Error.cpp:14:17: error: expected primary-expression before ‘int’
foo().Bar<int>();
^
Error.cpp:14:17: error: expected ‘;’ before ‘int’
The correct syntax is:
foo().template Bar<int>();
(Adding to #Dieter answer)
Otherwise you have to use a temporary:
Test1 tt = foo();
tt.Bar<int>();
(in this case you could have simply used t instead of tt, but that was not the point, of course).
Here is a busybox I wrote to play with the new feature in gcc-4.8.1+ (I think clang-2.9+ should do this too) for N2439 (ref-qualifiers for 'this'):
class Foo
{
public:
Foo(int i) : _M_i(i) { }
int bar() & { return _M_i /= 2; }
int bar() const & { return _M_i; }
int bar() && { return 2 * _M_i; }
private:
int _M_i = 42;
};
int
main()
{
Foo ph(333);
ph.bar();
const Foo ff(123);
ff.bar();
Foo(333).bar();
}
It looks to me reading the standard 8.3.5 that the three bar() methods should be overloadable. I get a linker error though:
[ed#localhost ref_this]$ ../bin/bin/g++ -std=c++11 -o ref_this ref_this.cpp
/tmp/ccwPhzqr.s: Assembler messages:
/tmp/ccwPhzqr.s:73: Error: symbol `_ZN3Foo3barEv' is already defined
If I comment out int bar() const & I am unable to resolve ff.bar();:
[ed#localhost ref_this]$ ../bin/bin/g++ -std=c++11 -o ref_this ref_this.cpp
ref_this.cpp: In function ‘int main()’:
ref_this.cpp:26:10: error: no matching function for call to ‘Foo::bar() const’
ff.bar();
^
ref_this.cpp:26:10: note: candidates are:
ref_this.cpp:11:7: note: int Foo::bar() &
int bar() & { return _M_i /= 2; }
^
ref_this.cpp:11:7: note: no known conversion for implicit ‘this’ parameter from ‘const Foo’ to ‘Foo&’
ref_this.cpp:13:7: note: int Foo::bar() &&
int bar() && { return 2 * _M_i; }
^
ref_this.cpp:13:7: note: no known conversion for implicit ‘this’ parameter from ‘const Foo’ to ‘Foo&&’
Is this a gcc bug or part of the standard?
I'm not on my computer with clang on it but what does clang say?
This feature is not supported by GCC up to version 4.8.0. It should be supported by GCC 4.8.1, which has not been officially released yet.
To the best of my knowledge, the only major compiler that supports reference qualifiers on member functions at the moment is Clang. As you can see from this example, your code compiles fine on Clang 3.2.
I am trying to figure out how binders work. I am working on the example from HERE. So I decided to extend it a bit but I can't figure out what is wrong
namespace mine {
using std::bind1st;
using std::bind2nd;
using std::function;
};
struct Foo {
Foo(int num) : num_(num) {}
void print_add(int i) const { std::cout << num_+i << '\n'; }
int num_;
};
int main()
{
using namespace mine;
// store a call to a member function
function<void(const Foo&, int)> f_add_display = &Foo::print_add;
Foo foo(314159);
f_add_display(foo, 1);
function<void(int)> foo_f_add_display = bind1st(f_add_display, foo);
foo_f_add_display(1);
// The problem is here <------------
function<void(const Foo&)> f_1_add_display = bind2nd(f_add_display, 1);
// f_1_add_display(foo);
}
The error message I am getting (from Intel CC, gdb is unintelligible)
Compilation finished with errors:
c++/4.7/backward/binders.h(160): error: invalid redeclaration of member function "std::binder2nd<_Operation>::operator()(const _Operation::first_argument_type &) const [with _Operation=std::function<void (const Foo &, int)>]" (declared at line 154)
operator()(typename _Operation::first_argument_type& __x) const
^
detected during instantiation of class "std::binder2nd<_Operation> [with _Operation=std::function<void (const Foo &, int)>]" at line 41 of "source.cpp"
compilation aborted for source.cpp (code 2)
What exactly is the problem here. Why is not possible to bind the second argument? or is it just some syntax error or something?
Code is HERE if anyone needs it.