I want to use std collections, for example std::vector in my xCode 4.5 project. Following the explanation here no type named 'shared_ptr' in namespace 'std' I changed my compiler options accordingly, but now when I come to build the project I get a bunch of errors such as Type float cannot be narrowed to GLubyte (aka unsigned char) in initializer list.
These errors are in a ccType.h, which is part of the Cocos2d library I'm using for my game.
I'm thinking the right thing to do is not to start debugging Cocos2d, but to change some of the compiler options.
How should I proceed?
Here is the code that causes the errors:
static inline ccColor4B ccc4BFromccc4F(ccColor4F c) {
return (ccColor4B){c.r*255.f, c.g*255.f, c.b*255.f, c.a*255.f};
}
The error message is exactly as I brought it above.
You should cast the type accordingly because C++11 disallow implicit conversion in initialisers lists, specifically in this case from float to unsigned char.
I guess this should be enough to solve the issue:
return (ccColor4B){static_cast<GLubyte>(c.r*255.f), static_cast<GLubyte>(c.g*255.f), static_cast<GLubyte>(c.b*255.f), static_cast<GLubyte>(c.a*255.f)};
Related
I try to follow the mantra of "no warnings." I try to write my code so that the compiler gives no warnings. I'm starting to use non-standard libraries for the first time.
I recently installed mlpack (with armadillo) using
vcpkg install mlpack:x64-windows
I built the library and it works. However, my compiler gives loads of warnings. These warnings seem like they could have been fixed by the developer, but I'm not sure.
Many of the warnings are about conversions. For example, the first such compiler warning is
'argument': conversion from 'size_t' to 'const arma::arma_rng::seed_type', possible loss of data
This occurs in the line
arma::arma_rng::set_seed(seed);
where seed is always of type const size_t. I made the following change:
arma::arma_rng::set_seed(static_cast<arma::arma_rng::seed_type>(seed));
This removed the warning. Another fix is to overload arma::arma_rng::set_seed to take a double and perform the conversion within the function.
Given that the armadillo library is so popular, I assume someone at some point would have recommended these changes. Is there a reason not to add static_cast here (i.e., is this an optimization)?
I dont have the library available, so I'll use a different example. Consider the following code is in the library. Its a completely made up example, but I hope it resembles the situation more or less:
#include <iostream>
void foo(unsigned char x) {
std::cout << (int)x << "\n";
}
void bar_warn(int a){
foo(a);
}
void bar_no_warn(int a){
foo(static_cast<unsigned char>(a));
}
gcc warns for bar_warn but not for bar_no_warn:
<source>:4:9: error: conversion from 'int' to 'unsigned char' may change value [-Werror=conversion]
4 | foo(a);
| ^
The std::cout << (int)x is just to see the effect of following user code:
int main() {
bar_warn(123456);
bar_no_warn(123456);
}
Output is
64
64
That is: The user code is completely fine. It has no errors nor does it trigger warnings. The issue is in the library code. The cast does change the value. And that is the case with or without the static cast. The static cast does not "fix" the cast in any way, it merely silences the warning.
If you can browse all usages of the cast and make sure that the reason for the warning never takes place then you can use a static_cast to silence the warning. In library code that is not always possible. The library cannot foresee all usages. User code might pass a value that is too big and a user might get unexpected results. In such case it is better for the library to warn rather than to silence the warning.
If you are bothered by the warning you can still silence it. For example gcc has -isystem to not output warnings in system headers. I suppose other compilers have similar option.
After updating to eclipse 2019-03-R or 2019-06-R eclipse shows errors for brace initializations.
e.g.
Invalid arguments for
std::string portStr{cfg.portStrInit};
Symbol 'counterStr' could not be resolved
class Counter
{
private:
std::string counterStr {};
public:
Counter(std::string _counterStr) : counterStr{_counterStr}
}
Our Windriver compiler compiles that code and eclipse versions 2018-12-R and older do not complain.
Problem happens to complex types e.g. std::string, std::vector, own defined classes ...
Using simple types int, long etc. works for eclipse.
e.g.
int test{cfg.testInit};
std:string{"Initializing with string and not with variable works for eclipse."};
For sure it might be better to initialize with () instead {} when passing variables for complex types. I am still surprised that our compiler does not complain about that kind of initialization.
std::string portStr(cfg.portStrInit); accepted by eclipse instead of
std::string portStr{cfg.portStrInit} not accepted by eclipse;
But it is grown code and we don't want to change hundreds of lines in order to satisfy eclipse.
Is there any possibility to make eclipse accepting this kind of initialization with {} for complex types?
I wasn't familiar with this. I searched it on google but didn't find my answer. So, posting my question.
Just tried following program:
#include <iostream>
class test
{
static char a[];
static int b[];
};
int main()
{
test t;
}
It compiles fine without any warnings on MSVS 2010 & g++ 4.8.1. It also compiles fine in C++14 compiler. (See live demo here.) So, where does C++ standard says about this? If I remove static keyword from the declaration of char array in test class, compiler gives an error ISO C++ forbids zero size array when I use -pedantic-errors command line option in g++ & /Zaoption in MSVS 2010 compiler it says error C2133: 'test::a' : unknown size. So, my questions are:
1) what is the use of unknown size static array?
2) How do I later specify size of them & access that array elements? I am really getting confused.
3) Why removing static keyword leads to compilation errors?
It would be better if someone would explain it using simple example.
Thanks.
The compiler doesn't care about the size. It's just a declaration for the static field, so telling it you have an array is enough. Size doesn't matter at this point.
You only have a declaration for the static field at this point. You never use those arrays and the compiler is permissive... it won't complain.
If you want to use them however, you'll need a definition. If you omit the size there, you'll get similar error messages you saw before.
There isn't anything special going on.
So i am currently importing a small C library into a new empty C++ project, but it simply won't compile. It works just fine compiling it with C, but it simply doesn't with C++. The only thing i am doing is including the header.
It seems to be a syntax fault, but it could be someting else. This is the only thing the compiler nags about:
error: expected unqualified-id before 'export'
bool (*export)(struct wld_exporter * exporter, struct wld_buffer * buffer, uint32_t type, union wld_object * object);
error: expected ')' before 'export'
Since i thought it was a syntax issue, i just didn't know what to do and tried stupid things like moving the asterix after export instead of prior hoping that it would work, but it obviously didn't.
I have no idea why the compiler can't recognize that it's supposed to be a function pointer, i have done function pointers c-style in c++ before without any issues.
I am using gcc and C++11 if that makes any difference.
export is a keyword in C++, you can't use it as an identifier.
List of keywords here: C++ keywords
export is a keyword in C++. You'll have to choose a different name.
I have the following code:
typedef void VOID;
int f(void);
int g(VOID);
which compiles just fine in C (using gcc 4.3.2 on Fedora 10). The same code compiled as C++ gives me the following error:
void.c:3: error: ‘<anonymous>’ has incomplete type
void.c:3: error: invalid use of ‘VOID’
Now, this is something in external library and I would like the owner to fix that problem. So I have a question - does C++ standard forbids this construct? Could you give me a pointer/citation? The only thing I can recall is that function declaration with (void) to signal empty parameter list is deprecated in C++, but I don't understand why typedefed VOID does not work.
Yes, as far as i know the second declaration is invalid in C++ and C89, but it is valid in C99.
From The C99 draft, TC2 (6.7.5.3/10):
The special case of an unnamed parameter of type void as the only item in the list
specifies that the function has no parameters.
It's explicitly talking about the type "void", not the keyword.
From The C++ Standard, 8.3.5/2:
If the parameter-declaration-clause is empty, the function takes no arguments. The parameter list (void) is equivalent to the empty parameter list.
That it means the actual keyword with "void", and not the general type "void" can also be seen from one of the cases where template argument deduction fails (14.8.2/2):
Attempting to create a function type in which a parameter has a type of void.
It's put clear by others, notable in one core language issue report here and some GCC bugreports linked to by other answers.
To recap, your GCC is right but earlier GCC versions were wrong. Thus that code might have been successfully compiled with it earlier. You should fix your code, so that it uses "void" for both functions, then it will compile also with other compilers (comeau also rejects the second declaration with that "VOID").
gcc bugs. Edit: since it wasn't clear enough, what I meant was gcc 4.3.2 was compiling it due to bugs. See #32364 and #9278.
I just put your code in a .cpp file, and it compiled with no problems in VS2005, SUSE, Redhat, and Solaris, so I guess your specific gcc version does not approve of this.
Gal