Clang 3.1 and user defined literals - c++

Clang 3.1 claims to support user defined literals. I can define this:
int operator"" _tryit(long double n) { return int(n); }
but when I try to use it I get an error:
int m = 5_tryit;
Invalid suffix '_tryit' on integer constant

5 cannot be implicitly converted to a long double in your case. You need to change it to 5.0 to make it a long double or explicitly invoke the function yourself for the implicit conversion to work:
int m = 5.0_tryit;
OR
int n = operator"" _tryit(5);
(tested both with clang version 3.1 (trunk) (llvm/trunk 155821))
This SO question has a good explanation of the rules.
(Also, as abarnert mentions, make sure you are passing the -std=c++11 flag to the compiler when compiling).

Related

C++ error: invalid suffix '.d' on floating constant

Hello I have the following declared arrays in C++:
int arr[5] = {1,2,3,4,0};
float arr2[10] = {1.2f,0.0f,2.0f,1.4f,0.0f,4.2f,5.3f,0.0f,0.0f,0.0f};
double arr3[6] = {0.0d,0.0d,5.3d,0.0d,0.0d,0.5d};
When I compile this code the compiler returns the following error:
error: invalid suffix '.d' on floating constant
I tried compiling using the flag -std=c++11 to try and see if it worked on C++ 11 but I get the same error. Can someone tell me where the error is? Thank you :)
Floating point literal suffixes are:
(no suffix) defines double
f F defines float
l L defines long double
Supposed you put the d to make the literal a double, you can remove it. I suppose gcc offers it as extension for the sake of consistency (allows to use a suffix also for doubles), but also gcc will accept no suffix and the type of the literal will be double.

C++ implicit numeric type demoting

Recently, I have noticed that C/C++ seems to be very permissible with numeric type conversion, as it implicitly casts a double to int.
Test:
Environment: cpp.sh, Standard C++ 14, Compilation warnings all set
Code:
int intForcingFunc(double d) {
return d; // this is allowed
}
int main() {
double d = 3.1415;
double result = intForcingFunc(d);
printf("intForcingFunc result = %f\n", result);
int localRes = d; // this is allowed
printf("Local result = %d\n", localRes);
int staticCastRes = static_cast<int>(d); // also allowed
printf("Static cast result = %d\n", staticCastRes);
}
No warnings are issues during compilation.
Documentation mentions tangentially the subject, but misses the exact case of the question:
C++ is a strong-typed language. Many conversions, specially those that imply a different interpretation of the value, require an explicit conversion, known in C++ as type-casting.
I have also tried in a managed language (C#) and all these cases are not allowed (as expected):
static int intForcingFunc(double d)
{
// Not legal: Cannot implicitly convert type 'double' to 'int'
// return d;
return Convert.ToInt32(d);
}
static void Main(string[] args)
{
double d = 3.1415;
double result = intForcingFunc(d);
Console.WriteLine("intForcingFunc result = " + result);
// Not legal: Cannot implicitly convert type 'double' to 'int'
// int localRes = d;
int localRes = (int)d;
Console.WriteLine("local result = " + result);
Console.ReadLine();
}
Why is this behavior allowed in a strong-typed language? In most cases, this is undesired behavior. One reason behind this seems to be lack of arithmetic overflow detection.
Unfortunately, this behavior is inherited from C, which notoriously "trusts the programmer" in these things.
The exact warning flag for implicit floating-point to integer conversions is -Wfloat-conversion, which is also enabled by -Wconversion. For some unknown reason, -Wall, -Wextra, and -pedantic (which cpp.sh provides) don't include these flags.
If you use Clang, you can give it -Weverything to enable literally all warnings. If you use GCC, you must explicitly enable -Wfloat-conversion or -Wconversion to get a warning when doing such conversions (among other useful flags you will want to enable).
If you want, you can turn it to an error with e.g. -Werror-conversion.
C++11 even introduced a whole new safer initialization syntax, known as uniform initialization, which you can use to get warnings for the implicit conversions in your example without enabling any compiler warnings:
int intForcingFunc(double d) {
return {d}; // warning: narrowing conversion of 'd' from 'double' to 'int' inside { }
}
int main() {
double d{3.1415}; // allowed
int localRes{d}; // warning: narrowing conversion of 'd' from 'double' to 'int' inside { }
}
You did not specify what compiler you are working with, but you probably have not, in fact, enabled all warnings. There's a story behind it, but the net effect is that g++ -Wall does not actually enable all warnings (not even close). Others (eg. clang++), in order to be drop-in replacement-compatible with g++ must do the same.
Here is a great post on setting strong warnings for g++: https://stackoverflow.com/a/9862800/1541330
If you are using clang++, things will be much easier for you: try using -Weverything. It does just what you expect (turns on every warning). You can add -Werror and the compiler will then treat any warnings that occur as compile-time errors. If you are now seeing warnings (errors) that you want to suppress, just add -Wno-<warning-name> to your command (eg. -Wno-c++98-compat).
Now the compiler will warn you whenever an implicit narrowing conversion (conversion with possible data loss that you didn't explicitly ask for) occurs. In cases where you want a narrowing conversion to occur, you must use an appropriate cast, eg:
int intForcingFunc(double d) {
return static_cast<int>(d); //cast is now required
}

Why function overloading causes no ambiguous error? ( c++ )

This code compiles without an error in gcc 4.6.1 and 4.8.1 ( eclipse auto compilation says: Candidates are: float pow(float, int) long double pow(long double,
int) double pow(double, int) ):
#include <iostream>
#include <cmath>
#include <vector>
using namespace std;
int main(void) {
const int i = 0, x = 2;
double y = pow( i, x );
y = log( i ) / log( x );
cout << y;
return 0;
}
Thank you very much. This code has performed some nice confusing at work. The compiler can be trusted?
You do not get any compilation errors, since the C++ standards says that your integer type is to be accepted and converted to double.
From the standard §26.8/11:
Moreover, there shall be additional overloads sufficient to ensure:
[...]
3. Otherwise, if any argument corresponding to a double parameter has type double or an integer type, then all arguments corresponding to double parameters are effectively cast to double.
Also see cppreference.com/.../pow where it says:
If any argument has integral type, it is cast to double.
I assume that the question is: "Why does function overloading cause ambiguity error?".
The answer is very clear in your case: There is not any version of pow(a, b) that accepts the parameter a as integer. Rather than displaying an error, the compiler tries to find a version of pow where there is a built-in (or custom) type conversion operator that can cast int into the type pow expects. It happens that there are 3 such functions and there is a conversion operator for each such function. That is why the compiler finds it ambiguous.
Because pow acceptes a double or a float as second parameter (your x). Here is the description for pow in C++11.
If your run the same code on VS2010 in will too issue an error.

Locating numerical errors due to Integer division

Is there a g++ warning or other tool that can identify integer division (truncation toward zero)? I have thousands of lines of code with calculations that inevitably will have numerical errors typically due to "float = int/int" that need to be located. I need a reasonable method for finding these.
Try -Wconversion.
From gcc's man page:
Warn for implicit conversions that may
alter a value. This includes
conversions between real and integer,
like "abs (x)" when "x" is "double";
conversions between signed and
unsigned, like "unsigned ui = -1"; and
conversions to smaller types, like
"sqrtf (M_PI)". Do not warn for
explicit casts like "abs ((int) x)"
and "ui = (unsigned) -1", or if the
value is not changed by the conversion
like in "abs (2.0)". Warnings about
conversions between signed and
unsigned integers can be disabled by
using -Wno-sign-conversion.
For C++, also warn for conversions
between "NULL" and non-pointer types;
confusing overload resolution for
user-defined conversions; and
conversions that will never use a type
conversion operator: conversions to
"void", the same type, a base class or
a reference to them. Warnings about
conversions between signed and
unsigned integers are disabled by
default in C++ unless
-Wsign-conversion is explicitly enabled.
For the following sample program (test.cpp), I get the error test.cpp: In function ‘int main()’:
test.cpp:7: warning: conversion to ‘float’ from ‘int’ may alter its value.
#include <iostream>
int main()
{
int a = 2;
int b = 3;
float f = a / b;
std::cout << f;
return 0;
}
I have a hard time calling these numerical errors. You asked for integer calculations, and got the correct numbers for integer calculations. If those numbers aren't acceptable, then ask for floating point calculations:
int x = 3;
int y = 10;
int z = x / y;
// "1." is the same thing as "1.0", you may want to read up on
// "the usual arithmetic conversions." You could add some
// parentheses here, but they aren't needed for this specific
// statement.
double zz = 1. * x / y;
This page contains info about g++ warnings. If you've already tried -Wall then the only thing left could be the warnings in this link. On second look -Wconversion might do the trick.
Note: Completely edited the response.
Remark on -Wconversion of gcc:
Changing the type of the floating point variable from float to double makes the warning vanish:
$ cat 'file.cpp'
#include <iostream>
int main()
{
int a = 2;
int b = 3;
double f = a / b;
std::cout << f;
}
Compiling with $ g++-4.7 -Wconversion 'file.cpp' returns no warnings (as $ clang++ -Weverything 'file.cpp').
Explanation:
The warning when using the type float is not returned because of the totally valid integer arithmetics, but because float cannot store all possible values of int (larger ones cannot be captured by float but by double). So there might be a change of value when assigning RHS to f in the case of float but not in the case of double. To make it clear: The warning is not returned because of int/int but because of the assignment float = int.
For this see following questions: what the difference between the float and integer data type when the size is same in java, Storing ints as floats and Rounding to use for int -> float -> int round trip conversion
However, when using float -Wconversion could still be useful to identify possible lines which are affected but is not comprehensive and is actually not intended for that. For the purpose of -Wconversion see docs/gcc/Warning-Options.html and here gcc.gnu.org/wiki/NewWconversion
Possibly of interest is also following discussion 'Implicit casting Integer calculation to float in C++'
The best way to find such error is to have really good unit tests. All alternatives are not good enough.
Have a look at this clang-tidy detection.
It catches cases like this:
d = 32 * 8 / (2 + i);
d = 8 * floatFunc(1 + 7 / 2);
d = i / (1 << 4);

sqrt(int_value + 0.0) -- Does it have a purpose?

while doing some homework in my very strange C++ book, which I've been told before to throw away, had a very peculiar code segment. I know homework stuff always throws in extra "mystery" to try to confuse you like indenting 2 lines after a single-statement for-loop. But this one I'm confused on because it seems to serve some real-purpose.
basically it is like this:
int counter=10;
...
if(pow(floor(sqrt(counter+0.0)),2) == counter)
...
I'm interested in this part especially:
sqrt(counter+0.0)
Is there some purpose to the +0.0? Is this the poormans way of doing a static cast to a double? Does this avoid some compiler warning on some compiler I do not use? The entire program printed the exact same thing and compiled without warnings on g++ whenever I left out the +0.0 part. Maybe I'm not using a weird enough compiler?
Edit:
Also, does gcc just break standard and not make an error for Ambiguous reference since sqrt can take 3 different types of parameters?
[earlz#EarlzBeta-~/projects/homework1] $ cat calc.cpp
#include <cmath>
int main(){
int counter=0;
sqrt(counter);
}
[earlz#EarlzBeta-~/projects/homework1] $ g++ calc.cpp
/usr/lib/libstdc++.so.47.0: warning: strcpy() is almost always misused, please use strlcpy()
/usr/lib/libstdc++.so.47.0: warning: strcat() is almost always misused, please use strlcat()
[earlz#EarlzBeta-~/projects/homework1] $
Also, here is the relevant part of my system libraries cmath I'm not too keen on templates, so I'm not sure what it's doing
using ::sqrt;
inline float
sqrt(float __x)
{ return __builtin_sqrtf(__x); }
inline long double
sqrt(long double __x)
{ return __builtin_sqrtl(__x); }
template<typename _Tp>
inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value,
double>::__type
sqrt(_Tp __x)
{ return __builtin_sqrt(__x);
Is this the poormans way of doing a static cast to a double?
Yes.
You can't call sqrt with an int as its parameter, because sqrt takes a float, double, or long double. You have to cast the int to one of those types, otherwise the call is ambiguous.
the reason for the expression counter + 0.0 is to explicitly make it a real number. if we donot add 0.0 the compiler will do implicit conversion
It's just another way to cast to a double. This is because sqrt doesn't accept ints. Because a double is higher it will merge the int into the 0.0. The same way can be done for converting from (int,double,float) to string.
double n = 0;
string m = ""+n;