Comparison of integers of different signs warning with Xcode - xcode

I use an open source to build my project. when I add EGOTextView to the project, it has Semantic Issues like:
Comparison of integers of different signs: 'int' and 'NSUInteger' (aka 'unsigned long')
Comparison of integers of different signs: 'NSInteger' (aka 'long') and 'NSUInteger' (aka 'unsigned long')
For example in source code:
for (int i = 0; i &lt lines.count; i++)//lines is an array
I notice the project has build configure file which includes:
// Make CG and NS geometry types be the same. Mostly doesn't matter on iPhone, but this also makes NSInteger types be defined based on 'long' consistently, which avoids conflicting warnings from clang + llvm 2.7 about printf format checking
OTHER_CFLAGS = $(value) -DNS_BUILD_32_LIKE_64
According to the comments, I guess it causes the problems.
However, I don't know the meaning for this OTHER_CFLAGS setting. And I also don't know how to fix it so that it can avoid the semantic issues.
Could any one help me?
Thanks!

Actually, I don't think turning off the compiler warning is the right solution, since comparing an int and an unsigned long introduces a subtle bug.
For example:
unsigned int a = UINT_MAX; // 0xFFFFFFFFU == 4,294,967,295
signed int b = a; // 0xFFFFFFFF == -1
for (int i = 0; i < b; ++i)
{
// the loop will have zero iterations because i < b is always false!
}
Basically if you simply cast away (implicitly or explicitly) an unsigned int to an int your code will behave incorrectly if the value of your unsigned int is greater than INT_MAX.
The correct solution is to cast the signed int to unsigned int and to also compare the signed int to zero, covering the case where it is negative:
unsigned int a = UINT_MAX; // 0xFFFFFFFFU == 4,294,967,295
for (int i = 0; i < 0 || (unsigned)i < a; ++i)
{
// The loop will have UINT_MAX iterations
}

Instead of doing all of this strange type casting all over the place, you ought to first notice why you are comparing different types in the first place: YOU ARE CREATING AN INT!!
do this instead:
for (unsigned long i = 0; i < lines.count; i++)//lines is an array
...and now you are comparing the same types!

The configuration option you're looking at won't do anything about the warning you quoted. What you need to do is go into your build settings and search for the "sign comparison" warning. Turn that off.

Instead of turning the warnings of you can also prevent them from occurring.
Your lines.count is of type NSUInteger. Make an int of this first, and then do the comparison:
int count = lines.count;
for (int i = 0; i < count; i++)

Related

Understanding solveInPlace operation in Eigen

I was trying to explore the option of "solveInPlace()" function while using LLT in Eigen3.3.7 to speed up the matrix inverse computation in my application.
I used the following code to test it.
int main()
{
const int M=3;
Eigen::Matrix<MyType,Eigen::Dynamic,Eigen::Dynamic> R = Eigen::Matrix<MyType,Eigen::Dynamic,Eigen::Dynamic>::Zero(M,M);
// to make sure full rank
for(int i=0; i<M*2; i++)
{
const Eigen::Matrix<MyType, Eigen::Dynamic,1> tmp = Eigen::Matrix<MyType,Eigen::Dynamic,1>::Random(M);
R += tmp*tmp.transpose();
}
std::cout<<"R \n";
std::cout<<R<<std::endl;
decltype (R) R0 = R; // saving for later comparison
Eigen::LLT<Eigen::Ref<Eigen::Matrix<MyType,Eigen::Dynamic,Eigen::Dynamic> > > myllt(R);
const Eigen::Matrix<MyType,Eigen::Dynamic,Eigen::Dynamic> I = Eigen::Matrix<MyType,Eigen::Dynamic,Eigen::Dynamic>::Identity(R.rows(), R.cols());
myllt.solveInPlace(I);
std::cout<<"I: "<<I<<std::endl;
std::cout<<"Prod InPlace: \n"<<R0*I<<std::endl;
return 0;
}
After reading the Eigen documentation, I thought that the input matrix (here "R") will be modified while computing the transform. To my surprise, I found that the results is store in "I". This was not expected as I defined "I" as a constant. Please provide an explanation for this behaviour.
The simple non-compiler answer would be that you're asking for the LLT to solve in-place (i.e. in the passed parameter) so what would you expect the result to be? Apparently, you would expect it to be a compiler error, as the "in-place" means change the parameter, but you're passing a const object.
So, if we search the Eigen docs for solveInPlace, we find the only item that takes a const reference to have the following note:
"in-place" version of TriangularView::solve() where the result is written in other
Warning
The parameter is only marked 'const' to make the C++ compiler accept a temporary expression here. This function will const_cast it, so constness isn't honored here.
The non-in-place option would be:
R = myllt.solve(I);
but that won't really speed up the calculation. In any case, benchmark before you decide that you need the in-place option.
You're question is in place, as what const_cast is meant to do is strip references/pointers of their const-ness iff the underlying variable is not const qualified* (cppref). If you were to write some examples
const int i = 4;
int& iRef = const_cast<int&>(i); // UB, i is actually const
std::cout << i; // Prints "I want coffee", or it can as we like UB
int j = 4;
const int& jRef = j;
const_cast<int&>(jRef)++; // Legal. Underlying variable is not const.
std::cout << j; // Prints 5
The case with i may well work as expected or not, we're dependent on each implementation/compiler. It may work with gcc but not with clang or MSVC. There are no guarantees. As you are indirectly invoking UB in your example, the compiler can choose to do what you expect or something else entirely.
*Technically it's the modification that's UB, not the const_cast itself.

Use of const in c++ [duplicate]

I have defined a constexpr function as following:
constexpr int foo(int i)
{
return i*2;
}
And this is what in the main function:
int main()
{
int i = 2;
cout << foo(i) << endl;
int arr[foo(i)];
for (int j = 0; j < foo(i); j++)
arr[j] = j;
for (int j = 0; j < foo(i); j++)
cout << arr[j] << " ";
cout << endl;
return 0;
}
The program was compiled under OS X 10.8 with command clang++. I was surprised that the compiler did not produce any error message about foo(i) not being a constant expression, and the compiled program actually worked fine. Why?
The definition of constexpr functions in C++ is such that the function is guaranteed to be able to produce a constant expression when called such that only constant expressions are used in the evaluation. Whether the evaluation happens during compile-time or at run-time if the result isn't use in a constexpr isn't specified, though (see also this answer). When passing non-constant expressions to a constexpr you may not get a constant expression.
Your above code should, however, not compile because i is not a constant expression which is clearly used by foo() to produce a result and it is then used as an array dimension. It seems clang implements C-style variable length arrays as it produces the following warning for me:
warning: variable length arrays are a C99 feature [-Wvla-extension]
A better test to see if something is, indeed, a constant expression is to use it to initialize the value of a constexpr, e.g.:
constexpr int j = foo(i);
I used the code at the top (with "using namespace std;" added in) and had no errors when compiling using "g++ -std=c++11 code.cc" (see below for a references that qualifies this code) Here is the code and output:
#include <iostream>
using namespace std;
constexpr int foo(int i)
{
return i*2;
}
int main()
{
int i = 2;
cout << foo(i) << endl;
int arr[foo(i)];
for (int j = 0; j < foo(i); j++)
arr[j] = j;
for (int j = 0; j < foo(i); j++)
cout << arr[j] << " ";
cout << endl;
return 0;
}
output:
4
0 1 2 3
Now consider reference https://msdn.microsoft.com/en-us/library/dn956974.aspx It states: "...A constexpr function is one whose return value can be computed at compile when consuming code requires it. A constexpr function must accept and return only literal types. When its arguments are constexpr values, and consuming code requires the return value at compile time, for example to initialize a constexpr variable or provide a non-type template argument, it produces a compile-time constant. When called with non-constexpr arguments, or when its value is not required at compile-time, it produces a value at run time like a regular function. (This dual behavior saves you from having to write constexpr and non-constexpr versions of the same function.)"
It gives as valid example:
constexpr float exp(float x, int n)
{
return n == 0 ? 1 :
n % 2 == 0 ? exp(x * x, n / 2) :
exp(x * x, (n - 1) / 2) * x;
}
This is an old question, but it's the first result on a google search for the VS error message "constexpr function return is non-constant". And while it doesn't help my situation, I thought I'd put my two cents in...
While Dietmar gives a good explanation of constexpr, and although the error should be caught straight away (as it is with the -pedantic flag) - this code looks like its suffering from some compiler optimization.
The value i is being set to 2, and for the duration of the program i never changes. The compiler probably noticed this and optimized the variable to be a constant (just replacing all references to variable i to the constant 2... before applying that parameter to the function), thus creating a constexpr call to foo().
I bet if you looked at the disassembly you'd see that calls to foo(i) were replaced with the constant value 4 - since that is the only possible return value for a call to this function during execution of the program.
Using the -pedantic flag forces the compiler to analyze the program from the strictest point of view (probably done before any optimizations) and thus catches the error.

Invalid assertion for overflow check Frama-C

While checking the overflow for short and char data type for add operation, the assertions inserted by Frama-C are seems to be incorrect:
For char and short data the maximum positive and negative values are of integer data type.
What could be the reason for this?
Integral types of rank less than int are converted to either int or unsigned when used in an arithmetic operation (see C11 6.3.1.8 Usual arithmetic conversions). This is why you see the cast to (int) for x and y. Note that by default -rte will not emit warning for downcasts, as they are not undefined behavior (6.3.1.3§3 indicates that signed downcasts are implementation defined and that an implementation may raise a signal). If you add the option -warn-signed-downcast, you'll see the assertions you were probably looking for, which are due to the cast into (char) of the result:
/*# assert rte: signed_downcast: (int)x+(int)y ≤ 127; */
/*# assert rte: signed_downcast: -128 ≤ (int)x+(int)y; */
Note that if you store the result into an int, as in
void main(void) {
char x;
char y;
int z;
x = 1;
y = 127;
z = x + y;
return;
}
There won't be any downcast warning (but the signed overflow warnings will be present).

OpenCL inconsistent results from kernel

When I try this I get the wrong result at 'output' even though I am copying the values of 'cum' array to output.
But if I rename the 'cum' array mentioned earlier in the code. I get the correct value of array. Therefore I am unable to reuse the result values.
The device has 8 cores with no shared memory.
Any and all comments/suggestions appreciated.
kernel void histogram(global unsigned int *input,
global unsigned int *output,
global unsigned int *frequency,
global unsigned int *cum,
unsigned int N)
{
int pid = get_global_id(0);
//cumulative sum
for(int i=0; i < 16; i++)
{
cum[(i*16)+(2*pid)+1] = frequency[(i*16)+(2*pid)] + frequency[(i*16)+(2*pid)+1];
}
barrier(CLK_GLOBAL_MEM_FENCE);
for(int i=0; i < 32; i++)
{
output[(i*8)+pid] = cum[(i*8)+pid];
}
barrier(CLK_GLOBAL_MEM_FENCE);
}
Make sure you understand parallel prefix sums. In particular I don't see a downsweep step of the total sum or parts:
Parallel Prefix Sum (Scan) with CUDA
I'd look in the TI's Keystone II SDK you're using in OpenCL device memory read/write issue to see if they have any scan or parallel prefix sum implementations or built in functions.

How to type cast a literal in C

I have a small sample function:
#define VALUE 0
int test(unsigned char x) {
if (x>=VALUE)
return 0;
else
return 1;
}
My compiler warns me that the comparison (x>=VALUE) is true in all cases, which is right, because x is an unsigned character and VALUE is defined with the value 0. So I changed my code to:
if ( ((signed int) x ) >= ((signed int) VALUE ))
But the warning comes again. I tested it with three GCC versions (all versions > 4.0, sometimes you have to enable -Wextra).
In the changed case, I have this explicit cast and it should be an signed int comparison. Why is it claiming, that the comparison is always true?
Even with the cast, the comparison is still true in all cases of defined behavior. The compiler still determines that (signed int)0 has the value 0, and still determines that (signed int)x) is non-negative if your program has defined behavior (casting from unsigned to signed is undefined if the value is out of range for the signed type).
So the compiler continues warning because it continues to eliminate the else case altogether.
Edit: To silence the warning, write your code as
#define VALUE 0
int test(unsigned char x) {
#if VALUE==0
return 1;
#else
return x>=VALUE;
#endif
}
x is an unsigned char, meaning it is between 0 and 256. Since an int is bigger than a char, casting unsigned char to signed int still retains the chars original value. Since this value is always >= 0, your if is always true.
All the values of an unsigned char can fir perfectly in your int, so even with the cast you will never get a negative value. The cast you need is to signed char - however, in that case you should declare x as signed in the function signature. There is no point lying to the clients that you need an unsigned value while in fact you need a signed one.
The #define of VALUE to 0 means that your function is reduced to this:
int test(unsigned char x) {
if (x>=0)
return 0;
else
return 1;
}
Since x is always passed in as an unsigned char, then it will always have a value between 0 and 255 inclusive, regardless of whether you cast x or 0 to a signed int in the if statement. The compiler therefore warns you that x will always be greater than or equal to 0, and that the else clause can never be reached.

Resources