Avoid g++ -Wuninitialized caused by library - g++

I am using a library that has a path that doesn't set a variable before it is returned, and g++ is giving me a warning about it. Is there a way for me to avoid this warning without changing the library and without disabling the warning?
#include<iostream>
// Begin Library function
inline int foo() {
int y;
if( /*something that will always be true*/ ) y = 42;
return y;
}
// end Library function
void bar(int x) {
std::cout << x;
}
int main() {
int x;
x = foo();
bar(x);
return 0;
}

How complex is the condition? In many cases, this will work to suppress such warnings:
if (! (/*something that will always be true*/))
__builtin_unreachable();
x = foo();
Or, if you build without -DNDEBUG:
assert(/*something that will always be true*/);
x = foo();
This way, when foo is inlined into main, GCC will realize that the condition can never be true, and not warn about the uninitialized value.

The error I am getting seems to have something to do with the fact that foo() is declared inline, because I found one way around the warning by using this approach: link
int main() {
int x;
volatile bool b{true};
if(b) x = foo();
else x = foo();
bar(x);
return 0;
}

Related

private data member in C++ OOP

I am new to OOP in C++. I got a doubt. I know it may be a silly doubt.
In the code below in main function, commented line will give error as I can not access private data memebers directly. but in the member function complex add(complex &C) I created a object temp of class complex. How can I access the data member of object temp directly and modify them as those are private. Like in the main function, should it not throw error? Is there any rule that in the member function of class we can access private data of a object of same class directly.
using namespace std;
class complex{
private:
int real;
int img;
public:
complex(int r = 0, int i = 0);
complex add(complex &C);
};
complex :: complex(int r, int i){
real = r;
img = i;
}
complex complex :: add(complex &C){
complex temp;
temp.real = real + C.real;
temp.img = img + C.img;
return temp;
}
int main() {
complex c1(3,4);
complex c2(5,7);
complex c3;
// c3.real = 3;
// c3.img = 5;
c3 = c1.add(c2);
return 0;
}
I try and stick to rule, keep your member variables private, if you need to change them or access them once the object is created, use a public get / set function.
e.g:
int complex::GetReal() const { return m_real; }
void complex::SetReal(const int i) { m_real = i; }

Cannot return a cli array of a generic type

I got this function
array<ItemType>^ GetNextItems(int n) {
auto ret = gcnew Collections::Generic::List < ItemType > ;
for (int i = 0; i < n; i++) {
auto item = GetNextItem();
if (item == ItemType()) break;
ret->Add(item);
}
return ret->ToArray();
}
But the compile gives me an error: cannot convert from 'cli::array< ItemType,1 > ^' to 'cli::array< ItemType,1 > ^'
ItemType is a template parameter ie.
generic <typename ItemType>
I've been staring at this for a while, I can't detect the fault. Why won't it compile?
If ItemType is a .NET/CLR type, then you'll need the ^-hat inside the return type declaration. The ^ is still not included in the actual type declaration.
So it would be something like this:
generic <typename ItemType>
ref class Test
{
array<ItemType ^>^
GetNextItems(int n)
{
List<ItemType ^> ^ ret = gcnew List<ItemType ^>(n);
...
return ret->ToArray();
}
};
Notice the added caret inside the <ItemType ^> return type declaration, but not in the class' generic definition.

Is there an equivalent to __attribute__((ns_returns_retained)) for a malloc'd pointer?

I'm looking for an annotation something like
-(SomeStruct *) structFromInternals __attribute__((returns_malloced_ptr))
{
SomeStruct *ret = malloc(sizeof(SomeStruct));
//do stuff
return ret;
}
to soothe the clang static analyzer beasts.
The only viable attributes link I can find is for GCC, but it doesn't even include ns_returns_retained, which is in an extension, I assume.
EDIT:
as to why this is needed, I have a scenario that I can't repro in a simple case, so it may have to do with a c lib in an Objective-C project... The gist is, I get a static analyzer warning that the malloc in createStruct is leaked:
typedef struct{
void * data;
size_t len;
}MyStruct;
void destroyStruct(MyStruct * s)
{
if (s && s->data) {
free(s->data);
}
if (s) {
free(s);
}
}
MyStruct * createStructNoCopy(size_t len, void * data)
{
MyStruct * retStruct = malloc(sizeof(MyStruct));
retStruct->len = len;
retStruct->data = data;
return retStruct;
}
MyStruct * createStruct(size_t len, void * data)
{
char * tmpData = malloc(len);
memcpy(tmpData, data, len);
return createStructNoCopy(len, tmpData);
}
MyStruct * copyStruct(MyStruct * s)
{
return createStruct(s->len, s->data);
}
The function annotation ownership_returns(malloc) will tell the Clang static analyser that the function returns a pointer that should be passed to free() at some point (or a function with ownership_takes(malloc, ...)). For example:
void __attribute((ownership_returns(malloc))) *my_malloc(size_t);
void __attribute((ownership_takes(malloc, 1))) my_free(void *);
...
void af1() {
int *p = my_malloc(1);
return; // expected-warning{{Potential leak of memory pointed to by}}
}
void af2() {
int *p = my_malloc(1);
my_free(p);
return; // no-warning
}
(See the malloc-annotations.c test file for some more examples of their use.)
At the moment, these annotations only take effect when the alpha.unix.MallocWithAnnotations checker is run (which is not run by default). If you're using Xcode, you'll need to add -Xclang -analyzer-checker=alpha.unix.MallocWithAnnotations to your build flags.

Function and delegate literals in D

Reading TDPL about function and delegate literals (5.6.1)
auto f = (int i) {};
assert(is(f == function));
I've got an assertion failure. Is this assertion correct?
I tried the following:
int z = 5;
auto f = (int i) { return i < 5; };
auto d = (int i) { return i < z; };
assert(is(typeof(f) == typeof(d)));
Assertion is valid there. Actually f is a delegate, not a function even if it doesn't need a frame pointer to access local variables. Is this a bug?
Also, I do not understand how assert(is(f == function)); should work.
I tried assert(is(f == delegate)); but it was failed also. What's wrong?
I use DMD32 D Compiler v2.053
UPDATE
auto f = (int i) {};
assert(is(typeof(f) == delegate))
Works correct, although there is no reason to be a delegate
But
auto f = function (int i) {};
assert(is(typeof(f) == void function(int))); // correct
assert(is(typeof(f) == function)); // failed!!!!!
Miracle. It seems D2 is not ready for production use yet.
"f" is a variable. The is expression compares types. This should work:
assert(is(typeof(f) == delegate));
If you want to create a function instead of a delegate, you can use the function literal syntax:
auto f = function (int i) { ... };
assert(is(typeof(f) == function)); // should be true
If the function literal syntax is not used, the literal is assumed to be delegate (Expressions, look under "Function Literals". This makes sense because D should not change the type based on the whether the body of the literal needs the stack frame (this would be super screwy). EDIT: TDPL does actually specify that the compiler will infer a function instead of a delegate if it can, regardless of the "function" keyword. This seems like a poor idea to me, so this might be something that has been dropped.
As to why the is(f == function) doesn't work, this looks like a regression.
You might find isFunctionPointer and isDelegate helpful.
Update:
See this, taken from traits.d:
template isSomeFunction(/+###BUG4217###+/T...)
if (/+###BUG4333###+/staticLength!(T) == 1)
{
enum bool isSomeFunction = isSomeFunction_bug4333!(T).isSomeFunction;
}
private template isSomeFunction_bug4333(T...)
{
/+###BUG4333###+/enum dummy__ = T.length;
static if (is(typeof(& T[0]) U : U*) && is(U == function))
// T is a function symbol.
enum bool isSomeFunction = true;
else static if (is(T[0] W) || is(typeof(T[0]) W))
// T is an expression or a type. Take the type of it and examine.
static if (is(W F : F*) && is(F == function))
enum bool isSomeFunction = true; // function pointer
else enum bool isSomeFunction = is(W == function) || is(W == delegate);
else enum bool isSomeFunction = false;
}
I think it might explain some things.
In other words:
void main()
{
static if (is(typeof(&main) T : T*)) static assert( is(T == function));
static if (is(typeof(&main) U)) static assert(!is(U == function));
}

char and initializer lists

I'd like to pass some numeric byte values via an initializer list a variadic template into an array. Is that possible?
template < int N > struct a {
char s[N];
template < typename ... A >
a (A ... _a) : s {_a...} {}
};
int main () {
// g++-4.5: error: narrowing conversion of »_a#0« from »int« to »char« inside { }
a < 3 > x { 1, 2, 3 };
}
What I can think of is
to use octal representation, '\001' etc., or
to cast every single value.
But both is not satisfying.
You don't need any complicated code
template < int N > struct a {
char s[N];
template < typename ... A >
a (A ... _a) : s {static_cast<char>(_a)...} {}
};
NOTE: All of this is unnecessary unless you have added functionality to the class so it's no longer an aggregate. (For example, other constructors, private members, a base class, etc.) The immediate way to fix the code in the question is simply to remove the constructor. So, let's assume there's something more to it.
I've seen some people trying to do things like this. It seems ugly, dealing with conversion semantics and trying to artificially re-create the functionality of a usual function call.
Here is a strategy to create an array class that simply has the right constructor in the first place.
Template aliasing would put the icing on the cake by hiding the ::type ugliness, but it's not in GCC yet.
template< typename ... NT >
struct var_ctor_array {
enum { size_e = 0 }; // only used for zero size case
};
template< typename T, typename ... NT >
struct var_ctor_array< T, NT ... > {
enum { size_e = 1 + sizeof...( NT ) };
T st[ size_e ];
var_ctor_array( T elem0, NT ... elemN )
: st { elem0, elemN ... } {}
};
template< typename T, size_t N, typename ... NT >
struct gen_var_ctor_array {
typedef typename gen_var_ctor_array< T, N-1, T, NT ... >::type type;
};
template< typename T, typename ... NT >
struct gen_var_ctor_array< T, 0, NT ... > {
typedef var_ctor_array< NT ... > type;
};
int main() { // usage
gen_var_ctor_array< char, 5 >::type five( 1, 2, 3, 4, 5 );
}
You're not actually using initializer lists. The constructor receives a variadic template and you initialize x with uniform initialization.
The only problem is I don't know of an elegant way of initializing an array with an initializer_list, AFAIK std::array should have a constructor that accepts initializer_list but it doesn't seem to be supported by g++ yet.
#include <utility>
template < int N > struct a {
char s[N];
a (std::initializer_list<char> list) {
if (N != list.size())
throw "list wrong size";
int i = 0;
const char* p = list.begin();
while(p != list.end())
s[i++] = *p++;
}
};