i get the following error message when trying to compile the following code on linux with gcc (GCC) 7.3.1 20180303 (Red Hat 7.3.1-5) while it works on windows without problems.
...
#include "DDImage/NoIop.h"
static const char* const CLASS = "RemoveChannels";
// -------------------- Header -------------------- \\
class RemoveChannels : public NoIop
{
public:
//! Default constructor.
RemoveChannels (Node* node) : NoIop(node)
{
this->_message = "\\w+";
this->operation = 1;
}
//! Virtual destructor.
virtual ~RemoveChannels () {}
void _validate(bool) override;
private:
//! Information private for the node.
ChannelSet channels;
std::regex rgx;
const char* _message;
int operation; // 0 = remove, 1 = keep
};
void RemoveChannels::_validate(bool for_real)
{
if (!this->_message) // Fast return if you don't have anything in there.
{
set_out_channels(Mask_None); // Tell Nuke we didn't touch anything.
return;
}
...
}
...
When compiling the above code i get the following error message on linux with gcc (on windows it works fine!).
Compiler error:
RemoveChannels.cpp:28:1: error: expected unqualified-id before ‘{’ token
{
^
RemoveChannels.cpp:65:6: error: ‘RemoveChannels’ has not been declared
void RemoveChannels::_validate(bool for_real)
^~~~~~~~~~~~~~
/RemoveChannels.cpp: In function ‘void _validate(bool)’:
RemoveChannels.cpp:67:8: error: invalid use of ‘this’ in non-member function
if (!this->_message) // Fast return if you don't have anything in there.
^~~~
...
If i remove this-> from the implementing function and just use _message it compiles and works without a problem.
Can anyone explain to me why this is happening and just on linux and not on windows?
Simple example
// -------------------- Header --------------------\\
class RemoveChannels
{
public:
int operation = 0;
};
int main ()
{
RemoveChannels r;
r.operation++;
}
when a line ends in a backslash, it is continued on the next line. That means class RemoveChannels has accidentally been commented out with a line comment leaking into the next line.
Solution: remove the backslash
// -------------------- Header --------------------
class RemoveChannels
{
public:
int operation = 0;
};
int main ()
{
RemoveChannels r;
r.operation++;
}
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.
While compile the below code got compilation error as
rise.h: error: pointer to incomplete class type is not allowed (fall->value = id)
While I added the function definition in dot cpp file, got linking error.
Note: Its working fine without inline.
File: fall.h
#include<rise.h>
class Fall
{
public:
char value;
};
File: rise.h
#include<fall.h>
class Fall;
class Rise
{
public:
Fall *fall;
inline void fill_the_val(struct ring *buf, char flag=false, char id = 0)
{
if(true == flag)
{
fall->value = id; //this line got compilation issue
}
}
};
File: rise.cpp
#include<fall.h>
#include<rise.h>
int main()
{
fill_the_val(buf, true, 1);
}
This is the code snippet that's giving this error. The line has been marked in the code snippet.
Code
class ignition::gazebo::systems::amclPrivate
{
public: Model model{kNullEntity};
public: bool updateAmclPose(const EntityComponentManager &_ecm);
public: std::string fixed_frame_;
public: std::string robot_frame_;
public: double rate_;
};
void amcl::Configure(const Entity &_entity,
const std::shared_ptr<const sdf::Element> &_sdf,
EntityComponentManager &_ecm,
EventManager &_eventMgr)
amcl_nh_.setCallbackQueue(& amcl_queue_);
amcl_pub_ = amcl_nh_.advertise<geometry_msgs::PoseWithCovarianceStamped>("amcl",1,true);
thread_ptr_ = std::make_shared<std::thread>();
{
// Set process rate
ros::Rate r(this->rate_);
while (this->amcl_nh_.ok())
{
this->updateAmclPose(const EntityComponentManager &_ecm); ---This line gives error
this->amcl_pub_.publish(this->msg_);
this->amcl_queue_.callAvailable(ros::WallDuration(0.0));
r.sleep();
}
}
Error
error: expected primary-expression before ‘const’
this->updateAmclPose(const EntityComponentManager &_ecm);
Error(updated after changing the line)
error: no matching function for call to
‘ignition::gazebo::v3::systems::amcl::updateAmclPose(const
ignition::gazebo::v3::EntityComponentManager&)’
this->updateAmclPose((const EntityComponentManager &)_ecm);
PS: The code snippet given above is a minimal example. Full implementation can be found here
PS: To avoid confusion, I haven't pasted full code. Can anybody suggest a solution?
Thanks
Having an issue getting this syntax to compile using the Visual Studio Nov 2012 CTP C++ Compiler ... Just wanted to be sure I wasn't missing something obvious.
Thanks!
EDIT: Removed Header to make it even simpler.
class Location
{
public:
Location();
};
class Shape
{
public:
Shape();
Shape(Location location);
};
// Doing this by pointer works ...
// Shape::Shape(Location* location){}
// Shape::Shape() : Shape(new Location()){}
Shape::Shape(Location location)
{
}
Shape::Shape()
: Shape(Location())
// error C2143: syntax error: missing ';' before ':'
{
// int x = 0;
// (void) x; // Added these two lines in some cases to get it to compile.
// These two lines do nothing, but get around a compiler issue.
}
// .h Simplification
class Location
{
public:
Location() {}
Location(Location const& other) {}
};
class Shape
{
Shape();
Shape(Location location);
};
// How about by value or reference?
Shape::Shape(Location location)
{
}
Shape::Shape(void)
: Shape(Location()) // error C1001: An internal error has occurred in the compiler.
{
}
int main() {}
The above code compiles and runs in gcc 4.7.2
I had to make a few changes to your code to make it compile. When simplifying things, try to keep the simplified code compiling. http://sscce.org/
To store the functions of a class in an array the following link http://sourcemaking.com/design_patterns/state/cpp/1 contains the code like below (Machine is the class name).
void(Machine:: *ptrs[])() =
{
Machine::off, Machine::on
};
The example in that link does not compile with the g++ compiler throwing error as below
$ g++ state.cpp
state.cpp: In function ‘int main()’:
state.cpp:89:18: error: invalid use of non-static member function ‘void Machine::off()’
state.cpp:89:32: error: invalid use of non-static member function ‘void Machine::on()’
state.cpp:97:15: error: expected unqualified-id before ‘*’ token
I am using g++ version 4.5.2
$ g++ --version
g++ (Ubuntu/Linaro 4.5.2-8ubuntu4) 4.5.2
Copyright (C) 2010 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Can an array be defined like this, i am not able to find an array defination like this any where else. If the example is correct why does not it compile.
If you define a typedef for your member functions you will simplify your code greatly.
class Machine
{
public:
void on(){}
void off(){}
};
int main()
{
typedef void (Machine::*MachineFunctionPtr)();
MachineFunctionPtr temp[] = { &Machine::off , &Machine::on };
//To invoke a function use this syntax
Machine mymachine;
((mymachine).*(temp[1]))();
The being said your error is due to missing "&" before the function name.
If you don't want to use typedef the correct way is something like
void(Machine:: *ptrs[])() =
{
&Machine::off, &Machine::on
};
Machine fsm;
int num;
while (1)
{
cout << "Enter 0/1: ";
cin >> num;
((fsm).*(ptrs[num]))();
}
To be able to add your member-function-pointers to your array you'll need to prepend their identifiers with the address-of operator &.
Example:
struct Obj {
void func_1 () {}
void func_2 () {}
};
int
main (int argc, char *argv[])
{
void (Obj::* pointers[]) () = {
&Obj::func_1, &Obj::func_2
};
}
This is the more c++ way to do it :
#include <vector>
#include <iostream>
struct A {
typedef void (A::*memfpt)();
A() : arr( { &A::foo, &A::bar } )
{}
void foo()
{
std::cout<<"foo"<<std::endl;
}
void bar()
{
std::cout<<"bar"<<std::endl;
}
std::vector< memfpt > arr;
};
int main() {
A a;
for ( auto &it : a.arr )
{
(a.*it)();
}
}
Instead of raw array, I used std::vector, and instead of that unspeakable abomination, I used the typedef.
Your specific example doesn't compile because :
line 97 : (fsm. *ptrs[num])(); should be (fsm.*ptrs[num])(); - you need to remove that space, because calling a pointer to member function should be done using .* or ->*
line 89 : Machine::off, Machine::on should be &Machine::off, &Machine::on because that is how you get pointer to member function.