I'm working on LLVM and found an interesting piece of code
case ARM::BMOVPCRX_CALL: {
EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::MOVr)
.addReg(ARM::LR)
.addReg(ARM::PC)
// Add predicate operands.
.addImm(ARMCC::AL)
.addReg(0)
// Add 's' bit operand (always reg0 for this)
.addReg(0));
EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::MOVr)
.addReg(ARM::PC)
.addReg(MI->getOperand(0).getReg())
// Add predicate operands.
.addImm(ARMCC::AL)
.addReg(0)
// Add 's' bit operand (always reg0 for this)
.addReg(0));
return;
}
My question is about .addReg and .addImm. I wouldn't say I'm new to C++ but I have never seen this type of code. What does it mean and what does it do? Why would anyone want to do something like this?
This pattern of writing software is called 'method chaining' or the 'named parameter idiom'.
For example, you may have a class:
class Example {
int a, b;
public:
Example &a(int const a) {this->a = a; return *this;}
Example &b(int const b) {this->b = b; return *this;}
};
int main(void) {
Example example;
example.a(5).b(6); //example.a is now 5, example.b is now 6
return 0;
}
For this example, it should be noted that there is nothing stopping you from calling example.b(6).a(5) to get an identical result.
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed last month.
Improve this question
On today's adventofcode, we had a pathfinding problem, with persistent states over multiple rounds.
I created a function called solve(startPoint, endPoint) which would calculate the steps to go from one waypoint to the other.
The code that worked fine:
int first = solve(start, end);
int second = solve(end, start);
int third = solve(start, end);
return first + second + third;
The code that did not work:
return solve(start, end) + solve(end, start) + solve(start, end);
And neither did
return (((solve(start, end)) + solve(end, start)) + solve(start, end));
How can I return the accumulated value in one line, without running in some sort of order issue?
The order of parts of a composed expression is not specified in C++ (see https://en.cppreference.com/w/cpp/language/eval_order). Therefore, it is not possible to gather these function calls in a single expression and guarantee a particular order of evaluation.
> How can I return the accumulated value in one line, without running in some sort of order issue?
Try this:
int a, b, c;
return (a = solve(start, end), b = solve(start, end), c = solve(start, end), a + b + c);
It guarantees the evaluation in order from left to right.
From eval_order:
Every value computation and side effect of the first (left) argument of the built-in comma operator , is sequenced before every value computation and side effect of the second (right) argument.
With persistent states, that code looks like this:
int a = c++ + c++ + c++;
there is no strict ordering about these operations. Partial results may even be cached in different CPU registers and get false result, even if the first c++ increments first, the second and third could be already cached on different CPU-registers for speed optimization, because there are likely multiple adder pipelines in a cpu core that can do it in (instruction-level) parallelism.
Try implementing a chain-calculation API like this:
return solve(s,e).addSolve(e,s).addSolve(s,e).result;
Here, the evaluation has to start from first and end at the last because this is just multiple lines of codes in disguise. Something like this:
class FOO
{
public:
BAR result;
FOO(){ result=0;}
FOO(BAR se){ result=se; }
// assuming solution is s+e
FOO solve(BAR s, BAR e)
{
return FOO(s+e);
}
FOO addSolve(BAR s, Bar e)
{
return FOO(result+s+e);
}
};
Ofcourse the upper example does not save the states in the original object. You need something like this really:
class FOO
{
public:
std::shared_ptr<BAR> result;
// creates original store
FOO()
{
result = std::make_shared<BAR>();
*result=0;
}
// re-uses original
FOO(BAR se, std::shared_ptr<BAR> original)
{
result = original;
*result=se;
}
// assuming solution is s+e
FOO solve(BAR s, BAR e)
{
return FOO(s+e,result);
}
FOO addSolve(BAR s, Bar e)
{
return FOO(*result + s + e,result);
}
};
So that you can still use the original object (the one that was created first) for the result.
Even if original object goes out of scope, the second and the third instances still have the exact same result.
If the initial conditions (parameterless default constructor) meet the requirements of addSolve, then you could simply call same addSolve method 3 times after renaming it to just solve:
// dereferencing explicitly
return *foo.solve(s,e).solve(e,s).solve(s,e).result;
// or implicitly from a method
return foo.solve(s,e).solve(e,s).solve(s,e).getResult();
If you make solve an object that holds the parameters and allows for lazy evaluation, you can overload the + operator for this type to guarantee the order of evaluation:
/**
* object simply stores the parameters for evaluation in operator+
*/
struct solve
{
int m_a;
int m_b;
constexpr solve(int a, int b) noexcept
: m_a(a), m_b(b)
{
}
int operator()() const
{
std::cout << "evaluating solve(" << m_a << ", " << m_b << ")\n";
return m_a + m_b;
}
};
int operator+(solve const& s1, solve const& s2)
{
// do operation of the first operand before the second
auto v1 = s1();
return v1 + s2();
}
int operator+(int s1, solve const& s2)
{
// first operand is already evaluated
return s1 + s2();
}
int main()
{
auto result = solve(1, 2) + solve(3, 4) + solve(5, 6);
std::cout << result << '\n';
return 0;
}
Output:
evaluating solve(1, 2)
evaluating solve(3, 4)
evaluating solve(5, 6)
21
In real code I recommend adding the constexpr modifier to solve::operator()() and the + operators, if possible btw...
Note that this may not be the best idea, since seeing the expression solve(1, 2) + solve(3, 4) + solve(5, 6) it's not obvious, that an order of evaluation is enforced here...
Inspired by another question regarding java-script language. Can the expression
(a==1)&&(a==2)&&(a==3)
evaluate to true in C++? (And if so, can it actually be useful?)
Yes it can:
class Foo
{
public:
bool operator==(int a)
{
return true;
}
};
Then, let a be of type Foo and voila.
Can this actually be useful? I don't really see it being useful no.
Can the expression evaluate to true in C++?
Yes, nothing is impossible...
struct A {
int x = 0;
};
bool operator==(A& a, int num) {
return ++a.x == num;
}
Then:
if ((a == 1) && (a == 2) && (a == 3)) {
std::cout << "meow" << std::endl;
}
prints meow.
But I have no idea of any practical usage of such weird overloading and, hopefully, will never see such code in production.
Could be somewhat useful.
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
struct Foo {
std::vector<int> v = {1,2,3};
};
bool operator==(const Foo& foo, int i) {
return std::any_of(foo.v.begin(), foo.v.end(), [=](int v){ return v == i; });
}
int main() {
Foo a;
if (a==1 && a==2 && a==3)
cout << "Really??" << endl;
return 0;
}
As it was noticed before, this trick could be performed with volatile. This is more honest approach compared to operator changing. Just let us use two threads:
volatile int a;
void changingValue(){
std::srand(unsigned(std::time(0)));
while (true) {
a = (rand() % 3 + 1);
}
}
void checkingValue(){
while (true) {
if (a == 1 && a == 2 && a == 3) {
std::cout << "Good choice!" << std::endl;
}
}
}
int main() {
std::thread changeValue = std::thread(changingValue);
changeValue.detach();
std::thread checkValue = std::thread(checkingValue);
checkValue.detach();
while (true){
continue;
}
}
Moreover, this code in my case is working well with no volatile declaration. As far as I understand, it should depend on compiler and processor. Maybe someone could correct it, if I'm wrong.
Other things not mentioned yet (source):
a might have overloaded operator int(), the operator for implicit conversion to int (instead of operator== as covered by other answers).
a might be a preprocessor macro.
Example of the latter:
int b = 0;
#define a ++b
if ((a==1)&&(a==2)&&(a==3))
std::cout << "aha\n";
Operator overloading and macros are trivial solutions to such a riddle.
And if so, can it actually be useful?
Well, with some imagination... One possible use case I can think of are unit tests or integration tests in which you want to make sure that your overloaded operator== for some class works correctly and you know for sure that it works incorrectly if it reports equality for different operands when it's not supposed to do that:
class A {
public:
A(int i);
bool operator==(int i) const;
// ...
};
A a(1);
if ((a==1)&&(a==2)&&(a==3)) {
// failed test
// ...
}
I assume a requirement is a valid program free of undefined behaviour. Otherwise simply introduce something like a data race and wait for the right circumstances to occur.
In a nutshell: Yes, it is possible for user-defined types. C++ has operator overloading, so the related answers from the JavaScript question apply. a must be a user-defined type because we compare against integers and you cannot implement operator overloads where all parameters are built-in types. Given that, a trivial solution could look like:
struct A {}
bool operator==(A, int) { return true; }
bool operator==(int, A) { return true; }
Can something like this be useful? As the question is stated: almost certainly not. There is a strong semantic meaning implied by the operator symbols used in their usual context. In the case of == that’s equality comparison. Changing that meaning makes for a surprising API, and that’s bad because it encourages incorrect usage.
However there are libraries that explicitly use operators for completely different purposes.
We have an example from the STL itself: iostream’s usage of << and >>.
Another one is Boost Spirit. They use operators for writing parsers in an EBNF like syntax.
Such redefinitions of the operator symbols are fine because they make it perfectly obvious that the usual operator symbols are used for a very different purpose.
Just to show my own ideas. I was thinking of some data structure like a stream buffer or a ring buffer.
We can with template inheritance "hide away the operator" and nothing will be altered in the data structure in itself but all checking will be done in the template superclass.
template<class C>
class Iterable{
C operator==(int a);
public:
Iterable(){pos = 0;}
int pos;
};
template<class C>
class Stream : public Iterable<Stream<C>>{
public:
Stream(C a){ m[0] = a; }
C m[32];
int operator==(int a){
return (m[this->pos++]==a); }
};
int main(){
Stream<int> a(1);
a.m[0] = 1; a.m[1] = 3; a.m[2] = 2;
if(a==1 && a==3 && a==2)
std::cout<<"Really!?"<<std::endl;
return 0;
}
In this case the == to an integer could be a short-cut for "is the next packet/element in the stream of this ID number" for example.
I am programming with C++11 and was wondering if there is a way to generate some code during execution.
For example instead of writing:
void b(int i){i+1}
void c(int i){i-1}
if(true) b()
else{ c() }
would there be a more straightforward way to say if true, then replace all + with - ?
Thank you and sorry if this question is stupid..
C++ has no native facilities for runtime code generation. You could of course invoke a C++ compiler from your program, then dynamically load the resulting binary, and call code from it, but I doubt this is the best solution to your problem.
If you are worried about repeatedly checking the condition, you shouldn't be. Modern CPUs will likely deal with this very well, even in a tight loop, due to branch prediction.
Last, if you really want to more dynamically alter the code path you take, you could use function pointers and/or polymorphism and/or lambdas.
An example with functions
typedef void (pFun*)(int); // pointer to function taking int, returning void
void b(int i){i+1}
void c(int i){i-1}
...
pFun d = cond ? b : c; // based on condition, select function b or c
...
pFun(i); // calls either b or c, effectively selecting + or -
An example with polymorphism
class Operator
{
public:
Operator() {}
virtual ~Operator() {}
virtual void doIt(int i) = 0;
};
class Add : public Operator
{
public:
virtual void doIt(int i) { i+1; }
};
class Sub : public Operator
{
public:
virtual void doIt(int i) { i-1; }
};
...
Operator *pOp = cond ? new Add() : new Sub();
...
pOp->doIt(i);
...
delete pOp;
Here, I have defined a base class with the doIt pure virtual function. The two child classes override the doIt() function to do different things. pOp will then point at either an Add or a Sub instance depending on cond, so when pOp->doIt() is called, the appropriate implementation of your operator is used. Under the covers, this does essentially what I outlined in the above example with function pointers, so choosing one over the other is largely a matter of style and/or other design constrains. They should both perform just as well.
An example with lambdas
This is basically the same as the first example using function pointers, but done in a more C++11 way using lambdas (and it is more concise).
auto d = cond ? [](int i) { i+1; }
: [](int i) { i-1; };
...
d(i);
Alternatively, you may prefer to have the condition inside the body of the lambda, for example
auto d = [&](int i) { cond ? i+1 : i-1; }
...
d(i);
C++ does not have runtime code generation since it's a compiled language.
In this case, you could put the sign into a variable (to be used with multiple variables.)
E.g.
int sign = (true ? 1 : -1);
result2 += sign;
result1 += sign;
Not necessarily a solution for your problem, but you could use
a template, instantiated on one of the operators in <functional>:
template <typename Op>
int
func( int i )
{
return Op()( i, 1 );
}
In your calling function, you would then do something like:
int (*f)( int i ) = condition ? &func<std::plus> : &func<std::minus>;
// ...
i = f( i );
It's possible to use lambdas, which may be preferable, but you can't use
the conditional operator in this case. (Every lambda has a unique type,
and the second and third operatands of the conditional operator must
have the same type.) So it becomes a bit more verbose:
int (*f)( int i );
if ( condition ) {
f = []( int i ) { return i + 1; }
} else {
f = []( int i ) { return i - 1; }
}
This will only work if there is no capture in the lambdas; when there is
no capture, the lambda not only generates an instance of a class with
a unique type, but also a function. Although not being able to use the
conditional operator makes this more verbose than necessary, it is still
probably simpler than having to define a function outside of the class,
unless that function can be implemented as a template, as in my first
example. (I'm assuming that your actual case may be significantly more
complicated than the example you've posted.)
EDIT:
Re lambdas, I tried:
auto f = c ? []( int i ) { return i + 1; } : []( int i ) { return i - 1; };
just out of curiosity. MSC++ gave me the expected error
message:
no conversion from 'someFunc::<lambda_21edbc86aa2c32f897f801ab50700d74>' to 'someFunc::<lambda_0dff34d4a518b95e95f7980e6ff211c5>'
but g++ compiled it without complaining, typeid(f) gave "PFiiI",
which I think is a pointer to a function. In this case, I'm pretty sure
that MSC++ is right: the standard says that each of the lambdas has
a unique type, and that each has a conversion operator to (in this
case) an int (*)( int ) (so both can be converted to the same
type—this is why the version with the if works). But the
specification of the conditional operator requires that either the
second operand can be converted to the type of the third, or vice versa,
but the results must be the type of one of the operands; it cannot be
a third type to which both are converted.
Update
I have created an qt bugticket hoping the documentation will be extended.
Original Question
Believing an Question from 2010 and the Qt Documentation, the operator==() doesn't work with custom types.
Quote:
bool QVariant::operator==(const QVariant & v) const
Compares this QVariant with v and returns true if they are equal; otherwise returns false.
QVariant uses the equality operator of the type() it contains to check for equality. QVariant will try to convert() v if its type is not the same as this variant's type. See canConvert() for a list of possible conversions.
Warning: This function doesn't support custom types registered with qRegisterMetaType().
I've tried to reproduce the repro case from the Stackoverflow Question from 2010 and the comparison worked without any problems for me.
I also went a step further and tried comparisons using an own class which also worked perfectly.
To reproduce, put the following code into any header:
enum MyEnum { Foo, Bar };
Q_DECLARE_METATYPE(MyEnum)
class MyClass
{
int value;
public:
MyClass() : value(0)
{
}
MyClass(int a) : value(a)
{
}
bool operator==(const MyClass &) const
{
Q_ASSERT(false); // This method seems not to be called
return false;
}
bool operator!=(const MyClass &) const
{
Q_ASSERT(false); // This method seems not to be called
return true;
}
};
Q_DECLARE_METATYPE(MyClass)
And the following code into any function:
QVariant var1 = QVariant::fromValue<MyEnum>(Foo);
QVariant var2 = QVariant::fromValue<MyEnum>(Foo);
Q_ASSERT(var1 == var2); // Succeeds!
var1 = QVariant::fromValue<MyEnum>(Foo);
var2 = QVariant::fromValue<MyEnum>(Bar);
Q_ASSERT(var1 != var2); // Succeeds!
QVariant obj1 = QVariant::fromValue<MyClass>(MyClass(42));
QVariant obj2 = QVariant::fromValue<MyClass>(MyClass(42));
Q_ASSERT(obj1 == obj2); // Succeeds!
obj1 = QVariant::fromValue<MyClass>(MyClass(42));
obj2 = QVariant::fromValue<MyClass>(MyClass(23));
Q_ASSERT(obj1 != obj2); // Succeeds!
I would guess that in newer qt versions the size of a type is aquired when the Q_DECLARE_METATYPE is used so the QVariant can compare values of unknown types bytewise.
But that's only a guess and I don't want to risk the stability of my application by guessing what qt does instead of relying on the documentation.
Can I find out, how the QVariant compares unknown types? I would prefer relying on specification than on implementation.
I'm afraid you'll need to rely on the code (and, being behaviour, it can't be changed without breaking), and not documentation. There's a surprise just below, though.
Here's the relevant code.
QVariant::operator== for types with unregistered operators will just use memcmp. The relevant snippet (in 5.1) is this:
bool QVariant::cmp(const QVariant &v) const
{
QVariant v1 = *this;
QVariant v2 = v;
if (d.type != v2.d.type)
// handle conversions....
return handlerManager[v1.d.type]->compare(&v1.d, &v2.d);
}
handlerManager is a global object that gets used to perform type-aware manipulations. It contains an array of QVariant::Handler objects; each of such objects contains pointers to perform certain operations on the types they know how to handle:
struct Handler {
f_construct construct;
f_clear clear;
f_null isNull;
f_load load;
f_save save;
f_compare compare;
f_convert convert;
f_canConvert canConvert;
f_debugStream debugStream;
};
Each and every of those members is actually a pointer to a function.
The reason for having this array of global objects is a bit complicated -- it's for allowing other Qt libraries (say, QtGui) to install custom handlers for the types defined in those libs (f.i. QColor).
The operator[] on the handlerManager will perform some extra magic, namely get the right per-module handler given the type:
return Handlers[QModulesPrivate::moduleForType(typeId)];
Now the type is of course a custom type, so the Handler returned here is the one the Unknown module. That Handler will use the customCompare function in qvariant.cpp, which does this:
static bool customCompare(const QVariant::Private *a, const QVariant::Private *b)
{
const char *const typeName = QMetaType::typeName(a->type);
if (Q_UNLIKELY(!typeName) && Q_LIKELY(!QMetaType::isRegistered(a->type)))
qFatal("QVariant::compare: type %d unknown to QVariant.", a->type);
const void *a_ptr = a->is_shared ? a->data.shared->ptr : &(a->data.ptr);
const void *b_ptr = b->is_shared ? b->data.shared->ptr : &(b->data.ptr);
uint typeNameLen = qstrlen(typeName);
if (typeNameLen > 0 && typeName[typeNameLen - 1] == '*')
return *static_cast<void *const *>(a_ptr) == *static_cast<void *const *>(b_ptr);
if (a->is_null && b->is_null)
return true;
return !memcmp(a_ptr, b_ptr, QMetaType::sizeOf(a->type));
}
Which, apart from a bit of error checking and handling shared and null variants in a special way, uses memcmp on the contents.
... only if the type is not a pointer type, it seems. Wonder why there's that code there...
Good news!
Starting with Qt 5.2, you can use QMetaType::registerComparator (see here) to make Qt invoke operator< and operator== on your custom type. Just add to your main:
qRegisterMetaType<MyClass>();
QMetaType::registerComparators<MyClass>();
And voilà, you'll hit the assert in your equality operator. QVariant::cmp now is:
QVariant v1 = *this;
QVariant v2 = v;
if (d.type != v2.d.type)
// handle conversions, like before
// *NEW IMPORTANT CODE*
if (v1.d.type >= QMetaType::User) {
// non-builtin types (MyClass, MyEnum...)
int result;
// will invoke the comparator for v1's type, if ever registered
if (QMetaType::compare(QT_PREPEND_NAMESPACE(constData(v1.d)), QT_PREPEND_NAMESPACE(constData(v2.d)), v1.d.type, &result))
return result == 0;
}
// as before
return handlerManager[v1.d.type]->compare(&v1.d, &v2.d);
It is said that the arrow operator is applied recursively. But when I try to execute the following code, it prints gibberish when it is supposed to print 4.
class dummy
{
public:
int *p;
int operator->()
{
return 4;
}
};
class screen
{
public:
dummy *p;
screen(dummy *pp): p(pp){}
dummy* operator->()
{
return p;
}
};
int main()
{
dummy *d = new dummy;
screen s(d);
cout<<s->p;
delete d;
}
What Stanley meant by “recursive” is just that the operator is applied to every returned object until the returned type is a pointer.
Which happens here on the first try: screen::operator -> returns a pointer. Thus this is the last call to an operator -> that the compiler attempts. It then resolves the right-hand sice of the operator (p) by looking up a member in the returned pointee type (dummy) with that name.
Essentially, whenever the compiler finds the syntax aᵢ->b in code, it essentially applies the following algorithm:
Is aᵢ of pointer type? If so, resolve member b of *aᵢ and call (*aᵢ).b.
Else, try to resolve aᵢ::operator ->
On success, set aᵢ₊₁ = aᵢ::operator ->(). Goto 1.
On failure, emit a compile error.
I’m hard-pressed to come up with a short, meaningful example where a chain of operator -> invocations even makes sense. Probably the only real use is when you write a smart pointer class.
However, the following toy example at least compiles and yields a number. But I wouldn’t advise actually writing such code. It breaks encapsulation and makes kittens cry.
#include <iostream>
struct size {
int width;
int height;
size() : width(640), height(480) { }
};
struct metrics {
size s;
size const* operator ->() const {
return &s;
}
};
struct screen {
metrics m;
metrics operator ->() const {
return m;
}
};
int main() {
screen s;
std::cout << s->width << "\n";
}
C++ Primer (5th edition) formulates it as follows on page 570:
The arrow operator never loses its fundamental meaning of member access. When we overload arrow, we change the object from which arrow fetches the specified member. We cannot change the fact that arrow fetches a member.
The deal is once screen::operator->() returns a pointer (dummy*) the recursion stops because built-in (default) -> in used on that pointer. If you want recursion you should return dummy or dummy& from screen::operator->()