Problem with __gmp_expr
Ulrich Drepper
drepper at gmail.com
Fri Jan 17 11:28:22 UTC 2014
In C++11 there are several situations where the result of a
computation using mp?_class objects is not immediately casted to a
mp?_class type. I haven't investigated further why this causes
problems but there are some. Take a look at the code below, it shows
two problem cases.
You can compile the code in four ways: with and without LAMBDA
defined, with and without OK defined. With OK defined the result of
the multiplication is forced to be of type mpq_class. Without it the
result is of type __gmp_expr. I've added the typeid use to show this.
Without OK defined the program crashes for me. This might actually
vary, I guess, depending on the compiler. valgrind shows the problem
as well:
==21979== Invalid read of size 4
==21979== at 0x4E5713E: __gmpq_set (set.c:30)
==21979== by 0x400AB2: main (in gmptest)
==21979== Address 0x4 is not stack'd, malloc'd or (recently) free'd
==21979==
==21979==
==21979== Process terminating with default action of signal 11 (SIGSEGV)
==21979== Access not within mapped region at address 0x4
==21979== at 0x4E5713E: __gmpq_set (set.c:30)
==21979== by 0x400AB2: main (in gmptest)
As you can see, a NULL pointer is used somewhere.
This is with 5.1.2 on x86-64 and i686. From reading about the changes
in 5.1.3 it doesn't seem there have been any changes in this area.
#include <gmpxx.h>
#include <iostream>
#include <typeinfo>
mpq_class a;
int
main()
{
mpq_class m = a / 2;
#ifndef LAMBDA
# ifdef OK
# define T mpq_class
# else
# define T auto
# endif
T i = -m * a;
std::cout << typeid(i).name() << std::endl;
a *= i;
#else
# ifdef OK
# define T -> mpq_class
# else
# define T
# endif
a *= [](mpq_class m) T { return -m * a; }(m);
#endif
}
More information about the gmp-bugs
mailing list