potentially uninitialized local pointer variable 'v' used in boost isomorphism.hpp - c++

I am new to boost and I was trying to use the isomorphism.hpp file for directed graphs.
while trying to run the code, in the boost library file I am seeing the error
1>c:\boost_1_55_0\boost\graph\isomorphism.hpp(142): error C4703: potentially uninitialized local pointer variable 'v' used
1>c:\boost_1_55_0\boost\graph\isomorphism.hpp(147): error C4703: potentially uninitialized local pointer variable 'v' used
It is being thrown from here,
BGL_FORALL_VERTICES_T(v, G1, Graph1){
f[v] = graph_traits<Graph2>::null_vertex(); //error thrown here
}
This is defined in boost/graphs/iteration_macros.hpp as seen below:
#define BGL_FORALL_VERTICES_T(VNAME, GNAME, GraphType) \
for (std::pair<typename boost::graph_traits<GraphType>::vertex_iterator, \
typename boost::graph_traits<GraphType>::vertex_iterator> BGL_RANGE(__LINE__) = vertices(GNAME); \
BGL_FIRST(__LINE__) != BGL_LAST(__LINE__); BGL_FIRST(__LINE__) = BGL_LAST(__LINE__)) \
for (typename boost::graph_traits<GraphType>::vertex_descriptor VNAME; \
BGL_FIRST(__LINE__) != BGL_LAST(__LINE__) ? (VNAME = *BGL_FIRST(__LINE__), true):false; \
++BGL_FIRST(__LINE__))
Where do we need to define this? Is this a known issue?

1>c:\boost_1_55_0\boost\graph\isomorphism.hpp(142): error C4703: potentially uninitialized local pointer variable 'v' used
Given...
BGL_FORALL_VERTICES_T(v, G1, Graph1)
...and...
#define BGL_FORALL_VERTICES_T(VNAME, GNAME, GraphType)
...we know v is known as VNAME within the macro.
The condition on the outer loop is:
BGL_FIRST(__LINE__) != BGL_LAST(__LINE__)
The condition on the inner loop is:
BGL_FIRST(__LINE__) != BGL_LAST(__LINE__) ? (VNAME = *BGL_FIRST(__LINE__), true):false;
Given the inner loop doesn't run unless the outer loop condition is satisfied, we can simplify:
true ? (VNAME = *BGL_FIRST(__LINE__), true):false;
(VNAME = *BGL_FIRST(__LINE__), true) ;
Clearly VNAME is always assigned to and never used uninitialised. Your compiler's analysis is flawed, and you should disable the warning (only for this specific code if at all possible), otherwise turn off any treat-warnings-as-errors compiler option so your build doesn't break completely or try another compiler.

Go to
Project > "ProjectName" Properties > C/C++ > General
There you should switch "SDL checks" from Yes to No.

Visual Studio 2019 (platform toolset v142) with C++20 enabled and warning level 4 gives a lot of warnings. To silence them:
#pragma warning(push)
#pragma warning(disable: 4244) // '-=': conversion from '__int64' to 'int', possible loss of data
#pragma warning(disable: 4267) // '=' : conversion from 'size_t' to 'int', possible loss of data
#pragma warning(disable: 4456) // declaration of 'xxx' hides previous local declaration
#pragma warning(disable: 4701) // potentially uninitialized local variable 'xxx' used
#pragma warning(disable: 4703) // potentially uninitialized local pointer variable 'xxx' used
#include <boost/graph/isomorphism.hpp>
#pragma warning(pop)

Related

Uninitialized register variable warning

I was working with a old codebase where I encountered few line of code which was causing lot of repeated warnings during compilation.
#define EXAMPLE(_ptr) \
{ \
register uintptr_t *__sp __asm__("sp"); \
(_ptr[0]) = (uintptr_t) __sp; \
asm volatile("sw $a0,%0" : "=m" (_ptr[1])); \
//SOME OTHER CODE HERE
}
the warning was:
warning: ‘__sp’ may be used uninitialized in this function
Can anyone help me in understanding what is happening in this code block and how to remove this warning.

C++ Random errors in a copied library

I copied a Big Int Library into my code and I'm having random errors in one of the classes. (The code is older)
One of my errors is in a define statement, not really sure how these work.
Everything under "tmpthis;" is giving an error.
#define DTRT_ALIASED(cond, op) \
if (cond) {\
BigUnsigned tmpThis;
tmpThis.op; //Error: no storage class or type specifier
*this = tmpThis; //Error: *this expected an identifier Error: No suitable conversion from "BigUnsigned" to "int" exists.
return; // Error: expected a declaration
} \
On top of that there are a few random if and for statements with the error "expected a declaration" and some variables with the error " no storage class or type specifier"
NOTE: these random errors also had instances where they were not errors also, it was inconsistent.
A bare-bones fix to the macro is:
#define DTRT_ALIASED(cond, op) \
if (cond) { \
BigUnsigned tmpThis; \
tmpThis.op; \
*this = tmpThis; \
return; \
}
This stands a chance of compiling when used in a function that doesn't return a value, if the reference to op in tmpThis.op makes sense to the compiler. It is somewhat peculiar (and limited) code, but there might be a use for it.

pragma warning( disable : 4700 ) not working in Visual Studio Express 2013

Compiling the following code in Release configuration with SDL checks disabled:
#include <immintrin.h>
int main()
{
const auto Set128Epi16 = []()
{
#ifdef NDEBUG
#pragma warning( push )
#pragma warning( disable : 4700 )
__m128i x = _mm_cmpeq_epi16( x,x );
x = _mm_srli_epi16( x,15 );
return _mm_slli_epi16( x,7 );
#pragma warning( pop )
#else
__m128i x = _mm_setzero_si128();
x = _mm_cmpeq_epi16( x,x );
x = _mm_srli_epi16( x,15 );
return _mm_slli_epi16( x,7 );
#endif
};
const auto xmm = Set128Epi16();
return *xmm.m128i_i32;
}
Gives the following output:
1>------ Rebuild All started: Project: pragmatic, Configuration: Release Win32 ------
1> main.cpp
1> Generating code
1>e:\projects\pragmatic\pragmatic\main.cpp(10): warning C4700: uninitialized local variable 'x' used
1>e:\projects\pragmatic\pragmatic\main.cpp(10): warning C4700: uninitialized local variable 'x' used
1>e:\projects\pragmatic\pragmatic\main.cpp(10): warning C4700: uninitialized local variable 'x' used
1>e:\projects\pragmatic\pragmatic\main.cpp(10): warning C4700: uninitialized local variable 'x' used
1>e:\projects\pragmatic\pragmatic\main.cpp(10): warning C4700: uninitialized local variable 'x' used
1> Finished generating code
1> pragmatic.vcxproj -> E:\Projects\pragmatic\Release\pragmatic.exe
========== Rebuild All: 1 succeeded, 0 failed, 0 skipped ==========
Why is the compiler ignoring my #pragma in this case. I have in the past successfully used this method to suppress the same warning code.
I copied this from https://msdn.microsoft.com/en-us/library/2c8f766e.aspx
For warning numbers in the range 4700-4999, which are the ones associated with code generation, the state of the warning in effect when the compiler encounters the open curly brace of a function will be in effect for the rest of the function. Using the warning pragma in the function to change the state of a warning that has a number larger than 4699 will only take effect after the end of the function. The following example shows the correct placement of warning pragmas to disable a code-generation warning message, and then to restore it.
So you probably need to put the pragma before the start of main, or maybe before the lambda would work, but I'm not sure about that.

Forcing preprocessor error with macro

Is there a way that I can force a preprocessor macro in C++ to emit an error? What I would like to do is define a macro UNKNOWN. I'm writing some code for a robot, and I don't yet know where all of the electronics are being plugged in. I'd like to be able to define the ports in some header file, like
const int MOTOR_PORT = 1;
const int FAN_PORT = 2;
//etc.
However, when I reach a port that I don't yet know, I want to be able to write something like
const int LED_PORT = UNKNOWN;
In debug mode, UNKNOWN would just be defined to some arbitrary value, like 0. However, when compiling in release mode, I want it to throw an error when UNKNOWN is used, so that unassigned ports don't end up in the final release. I know I can use the #error directive to force an error, but can I do something similar in a macro?
I've seen a solution using static_assert, but I unfortunately can't use C++11 for this platform.
Since #error can't result from a macro expansion, you can ensure that the macro expands to something that must be diagnosed, like a syntax error.
For example:
#ifdef RELEASE
#define UNKNOWN #Invalid_use_of_UNKNOWN
#else
#define UNKNOWN 0
#endif
const int MOTOR_PORT = 1;
const int FAN_PORT = 2;
const int LED_PORT = UNKNOWN;
int main(void) {
int x = LED_PORT;
}
The # character isn't part of C's basic character set, so its appearance outside a comment, character constant, or string literal should always result in an error message. ($ would work, except that accepting $ in identifiers is a common extension. ` would probably also work, but # stands out better.)
I've defined the macro so it produces a reasonable error message with gcc:
c.c:9:1: error: stray ‘#’ in program
c.c:9:22: error: ‘Invalid_use_of_UNKNOWN’ undeclared here (not in a function)
and with clang:
c.c:9:22: error: expected expression
const int LED_PORT = UNKNOWN;
^
c.c:2:17: note: expanded from:
#define UNKNOWN #Invalid_use_of_UNKNOWN
^
1 error generated.
(There's a _Pragma operator corresponding to the #pragma directive. It would be nice if there were an _Error operator as well, but there isn't.)
Well, this does not produce a complier error message like #error, but would compile in debug and fail in release:
#ifdef _DEBUG
# define UNKNOWN 1
#else
# define UNKNOWN
#endif
const int port1 = UNKNOWN; // fail in release
You could make a division by zero which will throw a compiler error:
#define UNKNOWN 0/0
The sizeof operator cannot be applied to an incomplete type, so try this:
// Declared, but not defined anywhere.
struct illegal_use_of_unknown_macro;
#define UNKNOWN (sizeof (illegal_use_of_unknown_macro))

C++ Macro improperly terminated macro invocation

In C++ is there a mechanism to allow non terminated macros to be expressed?
This is a contrived example:
#define MACRO(x, y) x + y
#define MACROC1(x) MACRO(x,
#define MACROC2(y) y)
//...expecting 3
int foo = MACROC1(1) MACROC2(2);
I receive the error improperly terminated macro invocation from MSVC.
When I run cl -E file.cpp I see that the code below has been generated:
int c = 1 + 1 + 2);
In visual studio compilation fails with errors:
error C2059: syntax error : ')'
IntelliSense: improperly terminated macro invocation
I don't think this is possible. The C precompiler expands macros depth-first, so the MACROC1 will be full expanded before the MACROC2 is even considered. Then, it will find the MACRO with and incomplete argument list and throws an error.
Generally speaking, you should avoid defining macros that build other macro calls. Compilers tend not to agree in what those mean.
Your code would translate to :
int foo = MACRO(1, 2;
Which is wrong - it is an incomplete (improperly terminated) invocation of macro MACRO.