Combining if constexpr() with non const condition - c++

I'm trying to something like this:
if( constexpr( TEMPLATE_BOOL_VALUE ) || bOhterBoolValue )
{
Foo();
}
else
{
Baa();
}
I usually use a preprocessor macro for such an if statement:
#define IF_COND if( constexpr( TEMPLATE_BOOL_VALUE ) || bOhterBoolValue )
IF_COND
{
Foo();
}
else
{
Baa();
}
In Visual Studio 2017, this worked (I should have but didn't check the generated code, but the compiler accepted this syntax).
In Visual Studio 2019, now there is an error "C2760" because it only allows:
if constexpr( TEMPLATE_BOOL_VALUE )
{
Foo();
}
else if( bOhterBoolValue )
{
Foo();
}
else
{
Baa();
}
Is there another way for doing this without typing two times Foo()?
Hope you can help. I don't wanna get two identical cases.

Since Foo(); branch is valid (i.e. compiles) regardless of whether TEMPLATE_BOOL_VALUE is true or not, there no need to use if constexpr.
Simply use if (TEMPLATE_BOOL_VALUE || bOhterBoolValue).

Related

Why does va_arg(va_list, type) give me a C6285 warning?

Everything is working as intended, and I get the values I need from va_arg(va_list, type), but I get this warning everywhere I call va_arg:
Warning C6285 (<non-zero constant> || <non-zero constant>) is always a non-zero constant. Did you intend to use the bitwise-and operator?
Example code:
void Logger::log(LogLevel level, const char* location, uint32_t line, const char* format, ...)
{
va_list arg_ptr;
va_start(arg_ptr, format);
while (*format) {
// ...
if (*format == 'd') { //
int i = va_arg(arg_ptr, int); // <-- Warning is reported here
// ...
}
// ...
++format;
}
// ...
va_end(arg_ptr);
}
Why do I get this warning and how can I get rid of it?
I'm using Visual Studio Community 2019 with Visual C++ 2019
C6### error codes are IntelliSense codes. These are based on heuristics and are meant to point the attention to potential errors, but can also result in false-positives, which seems to be the case here; it's probably triggering on the va_arg implementation in the CRT:
#define __crt_va_arg(ap, t) \
((sizeof(t) > sizeof(__int64) || (sizeof(t) & (sizeof(t) - 1)) != 0) \ // <== Here
? **(t**)((ap += sizeof(__int64)) - sizeof(__int64)) \
: *(t* )((ap += sizeof(__int64)) - sizeof(__int64)))
I would simply ignore it ...
If it bothers you, report it to the vendor: Help → Send Feedback → Report a Problem...

Why does this if/else statement appear to be optimized away?

This is the code in question:
void DeckTug::StickCallback(unsigned long long evtID, DWORD value)
{
long int val = value;
if (evtID == stickXInputID || evtID == stickAxisXInputID)
stickXpct = (((double)val)) / 325.94;
else if (evtID == stickYInputID || evtID == stickAxisYInputID) {
stickYpct = (((double)val)) / 325.94;
if(isAuto)
if ((stickYpct < 0.0)) {
acPullingTug = true;
tugTBoffset = tugReversed ? towbarAttachAft * (-1.0) : towbarAttachForward;
}
else {
acPullingTug = false;
tugTBoffset = tugReversed ? towbarAttachAft * (-1.0) : towbarAttachForward;
}
}
}
When I compile a debug build, this runs perfectly. When I compile a release build, it does not work. When I attach the visual studio debugger to the release version, I can break on the first if statement and on the closing brace of the function, but I cannot hit a break point anywhere else, and neither stickXpct or stickYpct are ever being assigned anything, although in the debugger I can see that "value" has a valid value, and "evtID" DOES equal one of inputIDs.
In conclusion, it looks to me like, in the release version of the code only, both the first "if" statement and the first "else if" statement only evaluate to false, even when one of them should evaluate to true. Does anyone know what is going on here? because I don't.
Thanks so much,
Farley
Edit: changed answer in response to comments
Try adding volatility
void DeckTug::StickCallback(unsigned long long evtID, DWORD value)
{
long int val = value;
volatile unsigned long long _evtID = evtID;
if (_evtID == stickXInputID || _evtID == stickAxisXInputID)
stickXpct = (((double)val)) / 325.94;
else if (_evtID == stickYInputID || _evtID == stickAxisYInputID) {
stickYpct = (((double)val)) / 325.94;
if(isAuto)
if ((stickYpct < 0.0)) {
acPullingTug = true;
tugTBoffset = tugReversed ? towbarAttachAft * (-1.0) : towbarAttachForward;
}
else {
acPullingTug = false;
tugTBoffset = tugReversed ? towbarAttachAft * (-1.0) : towbarAttachForward;
}
}
}
That should prevent the compiler from optimizing those branches until you can track down why it wants to optimize those branches away.

MISRA-C++:2008[8-4-3] : return in all exit path in function

When testing my code (static analysis) to see if i respect misra c++ 2008, i get the following error
Function does not return a value on all paths.
The function looks like
int* Dosomething(string v)
{
int* retvalue = NULL;
if( 0 == exists(v) )
{
throw("error: value doesn't exist");
}
else
{
retvalue = dosomecomputations(v);
}
return retvalue;
}
I really need to throw an exception, because depending of the error the caller shall do something. The possible list of errors can be big and it is not just that the value doesn't exist as in this sample of code.
How can i manage it? I think that in this case the tool i'm using should not see it as a non-compliance to misra.
Thanks for your advise.
rony.
The following code should not report any warnings/errors with MISRA C++ 2008 rules applied. So most likely it's an issue with your tool - or the posted code is not the affected part.
#include <string>
int exists(std::string v){ (void)v; return 1; }
int* dosomecomputations(std::string v){ (void)v; return NULL; }
int* dosomething(std::string v){
int* retvalue = NULL;
if( 0 == exists(v) ){
throw("error: value doesn't exist");
}else{
retvalue = dosomecomputations(v);
}
return retvalue;
}
Try to check just the snippet above with your MISRA checker and see if it's still reporting anything. If the problem persists I would just contact the toolvendor and ask him about that issue.

'wcsncasecmp' was not declared in this scope

I have included file JSONValue from simpleJSON, which is used for parsing the json string.
While compiling I am getting this error that 'wcsncasecmp' was not declared in this scope.
on this line. While searching more i ot that wcsncasecmp is a GNU-specific function, I am using windows, so can anyone help me out.
else if ((simplejson_wcsnlen(*data, 4) && wcsncasecmp(*data, L"true", 4) == 0) || (simplejson_wcsnlen(*data, 5) && wcsncasecmp(*data, L"false", 5) == 0))
{
bool value = wcsncasecmp(*data, L"true", 4) == 0;
(*data) += value ? 4 : 5;
return new JSONValue(value);
}
.
I'll be greatful for any help.
On windows there is _wcsnicmp that you can use.
More ref: _strnicmp, _wcsnicmp, _mbsnicmp, _strnicmp_l, _wcsnicmp_l, _mbsnicmp_l
Please define WIN32 macro in your source or in Visual Studio please add it to the project / Properties / C/C++ / Preprocessor definition.
#define WIN32
Internally it will define wcsncasecmp as _wcsnicmp like Rohan has already mentioned.
This is a known problem of SimpleJSON.
// Win32 incompatibilities
#if defined(WIN32) && !defined(__GNUC__)
#define wcsncasecmp _wcsnicmp
static inline bool isnan(double x) { return x != x; }
static inline bool isinf(double x) { return !isnan(x) && isnan(x - x); }
#endif

Is there a better way? While loops and continues

There are many functions within the code I am maintaining which have what could be described as boilerplate heavy. Here is the boilerplate pattern which is repeated ad nausea throughout the application when handling DB I/O with a cursor:
if( !RowValue( row, m_InferredTable->YearColumn(), m_InferredTable->YearName(), m_InferredTable->TableName(), value )
|| !IsValidValue( value ) )
{
GetNextRow( cursor, m_InferredTable );
continue;
}
else
{
value.ChangeType(VT_INT);
element.SetYear( value.intVal );
}
The thing is not all of these statements like this deal with ints, this "element" object, the "year" column, etc. I've been asked to look at condensing it even further than it already is and I can't think of a way to do it. I keep tripping over the continue statement and the accessors of the various classes.
Edit: Thanks to all those that commented. This is why I love this site. Here is an expanded view:
while( row != NULL )
{
Element element;
value.ClearToZero();
if( !GetRowValue( row, m_InferredTable->DayColumn(), m_InferredTable->DayName(), m_InferredTable->TableName(), value )
|| !IsValidValue( value ) )
{
GetNextRow( cursor, m_InferredTable );
continue;
}
else
{
value.ChangeType(VT_INT);
element.SetDay( value.intVal );
}
And things continue onward like this. Not all values taken from a "row" are ints. The last clause in the while loop is "GetNextRow."
Okay, from what you've said, you have a structure something like this:
while (row!=NULL) {
if (!x) {
GetNextRow();
continue;
}
else {
SetType(someType);
SetValue(someValue);
}
if (!y) {
GetNextRow();
continue;
}
else {
SetType(SomeOtherType);
SetValue(someOtherValue);
}
// ...
GetNextRow();
}
If that really is correct, I'd get rid of all the GetNextRow calls except for the last one. I'd then structure the code something like:
while (row != NULL) {
if (x) {
SetType(someType);
SetValue(someValue);
}
else if (y) {
SetType(someOtherType);
SetValue(SomeOtherValue);
}
// ...
GetNextRow();
}
Edit: Another possibility would be to write your code as a for loop:
for (;row!=NULL;GetNextRow()) {
if (!x)
continue;
SetTypeAndValue();
if (!y)
continue;
SetTypeandValue();
// ...
Since the call to GetNextRow is now part of the loop itself, we don't have to (explicitly) call it each time -- the loop itself will take care of that. The next step (if you have enough of these to make it worthwhile) would be to work on shortening the code to set the types and values. One possibility would be to use template specialization:
// We never use the base template -- it just throws to indicate a problem.
template <class T>
SetValue(T const &value) {
throw(something);
}
// Then we provide a template specialization for each type we really use:
template <>
SetValue<int>(int value) {
SetType(VT_INT);
SetValue(value);
}
template <>
SetValue<float>(float value) {
SetType(VT_FLOAT);
SetValue(value);
}
This lets you combine a pair of calls to set the type and the value into a single call.
Edit: As far as cutting processing short goes, it depends -- if parsing a column is expensive (enough to care about) you can simply nest your conditions:
if (x) {
SetTypeAndValue();
if (y) {
SetTypeAndValue();
if (z) {
SetTypeAndValue();
and so on. The major shortcoming of this is that it'll get pretty deeply nested if (as you've said) you have 20+ conditions in a single loop. That being the case, I'd probably think hard about the for-loop based version I gave above.
Why not make a function to do all the work?
bool processElement(Element& element, Row* row, int value, Table& m_InferredTable, /*other params*/)
{
if( !GetRowValue( row, m_InferredTable->DayColumn(), m_InferredTable->DayName(), m_InferredTable->TableName(), value )
|| !IsValidValue( value ) )
{
GetNextRow( cursor, m_InferredTable );
return true;
}
else
{
value.ChangeType(VT_INT);
element.SetDay( value.intVal );
}
return false;
}
In your loop
while (row != NULL)
{
if (processElement(element, row, value, m_InferredTable))
continue;
// other code
}
Why not invert your if-test?
if (RowValue(row, m_InferredTable->YearColumn(), m_InferredTable->YearName(), m_InferredTable->TableName(), value )
&& IsValidValue( value ))
{
value.ChangeType(VT_INT);
element.SetYear( value.intVal );
}
else
{
GetNextRow( cursor, m_InferredTable );
}
My instinctual approach is to build a polymorphic approach here, where you eventually wind up doing something like(modulo your language and exact logic):
db_cursor cursor;
while(cursor.valid())
{
if(cursor.data.valid())
{
process();
}
cursor.next();
}
db_cursor would be a base class that your different table type classes inherit from, and the child classes would implement the validity functions.
Move it into a template function, templated on the element type (e.g. integer), which you can call over and over. Vary the behavior per data type with a trait template.
template <typename T> struct ElemTrait<T> {};
template <> struct ElemTrait<int> {
static inline void set(Val &value, Elem &element) {
value.ChangeType(VT_INT);
element.SetYear(value.intVal);
}
};
// template <> struct ElemTrait<float> { ... };
template <typename T>
void do_stuff( ... ) {
// ...
if (!RowValue(row,
m_InferredTable->YearColumn(),
m_InferredTable->YearName(),
m_InferredTable->TableName(), value)
|| !IsValidValue(value)
) {
GetNextRow(cursor, m_InferredTable);
continue;
} else {
ElemTrait<T>::set(value, element);
}
// ...
}
You can take out all the GetNextRow calls and the else clauses:
for (row = GetFirstRow () ; row != null ; GetNextRow ())
{
Element element;
value.ClearToZero();
if( !GetRowValue( row, m_InferredTable->DayColumn(), m_MetInferredOutTable->DayName(), m_MetInferredOutTable->TableName(), value )
|| !IsValidValue( value ) )
{
continue;
}
value.ChangeType(VT_INT);
element.SetDay( value.intVal );
}