How to detect cast from bool - c++

I found error in my code that I think should be marked with warning. Compiled with /W4 but it don't show any warning (only about unreferenced formal parameter).
#include <cstdio>
void A(int item, unsigned int count, unsigned team_count)
{
printf("A, count, team count\n");
}
void A(int item, unsigned int count=1, bool is_team=true)
{
printf("A, count, is_team\n");
return A(item, count, is_team ? count : 0);
}
int main()
{
A(0, false); // <- bool to unsigned int
return 0;
}
Here bool is casted to unsigned int. Is there any way to detect that?
Tried Cppcheck but it don't find this.

Here is an example how you can achieve what you want
#include <iostream>
void f( int ) { std::cout << "f( int )" << std::endl; }
void f( bool ) = delete;
int main()
{
f( true );
return 0;
}
Compiler error
prog.cpp:8:10: error: use of deleted function ‘void f(bool)’
f( true );
^
Applied to your code the example will look like
#include <iostream>
void A( int item, unsigned int count, unsigned team_count )
{
std::cout << "A, count, team count" << std::endl;
}
void A( int item, unsigned int count = 1, bool is_team = true )
{
std::cout << "A, count, is_team" << std::endl;
return A( item, count, is_team ? count : 0 );
}
void A( int, bool ) = delete;
int main()
{
A( 0, false );
return 0;
}
Error:
prog.cpp:18:14: error: use of deleted function ‘void A(int, bool)’
A( 0, false );
^

The standard says this is acceptable §4.7/p4 Integral Conversions:
If the source type is bool, the value false is converted to zero and the value true is converted to one.
Regarding how to detect this (since it's not an error) and depending on your use-case, you could either do some clang-tooling yourself or write a wrapper with some template deduction magic on the lines of:
#include <cstdio>
#include <type_traits>
template<typename T, typename U>
void A(int item, T, U) {
static_assert(!std::is_same<T, unsigned int>::value ||
(!std::is_same<U, unsigned int>::value &&
!std::is_same<U, bool>::value),
"Something was wrong");
}
template<>
void A(int item, unsigned int count, unsigned int team_count)
{
printf("A, count, team count\n");
}
template<unsigned int count = 1, bool is_team = true>
void A(int item, unsigned int, bool)
{
printf("A, count, is_team\n");
return A(item, count, is_team ? count : 0);
}
int main()
{
// A(0, false); - not acceptable
// A(0, 22); - not acceptable
A(0, static_cast<unsigned int>(2), false);
A(0, static_cast<unsigned int>(33), static_cast<unsigned int>(45));
return 0;
}
Example
Note that the base template deduction mechanism doesn't require C++11, although some functions used above do.

A very safe way to prevent such things is to wrap your count types in classes without implementing automatic conversions.
class Count
{
private:
int m_count;
public:
explicit Count(int count) : m_count(count)
{
assert(m_count >= 0);
}
int Get() const { return m_count; }
};
class TeamCount
{
private:
int m_count;
public:
explicit TeamCount(int count) : m_count(count)
{
assert(m_count >= 0);
}
int Get() const { return m_count; }
};
// ...
void A(int item, Count count, TeamCount team_count);
void A(int item, Count count = Count(1), bool is_team = true);
// ...
A(0, false); // <- compiler error
A(0, TeamCount(0), false); // <- compiler error
A(0, Count(0), false); // OK
You can do a similar thing with your other primitive type parameters.

Related

Wrapping an object and pretend it's an int

I have a class Object that I'd like to use as if it were an int. In other words I want to pass this object to functions that accepts int, int* or int& so that the functions "see" actually ony the wrapped int value.
The code below illustrates what I want to do. I was able to write the code for int and int* but I'm not able to write the code for int&.
#include <cassert>
class Object
{
public:
int bla = 0;
int val = 0; // the int being wrapped
Object(int v) : val(v) {};
operator int() const { return val; };
int *operator &() { return &val; };
#if 1
int & operator() { return val; }; // << does not compile
#endif
};
int func(int val) {
return val * 2;
}
void Bar(int* pval, int val) {
*pval = val;
}
void Foo(int & pval, int val) {
pval = val;
}
int main() {
int val;
Bar(&val, 123);
assert(val == 123);
Foo(val, 789);
assert(val == 789);
Object o(8);
assert(func(o) == 2 * 8); // operator int()
Bar(&o, 1234); // int *operator &()
assert(o.val == 1234);
#if 1
Foo(o, 456); // << does not compile
assert(o.val == 456);
#endif
}
If #if 1 is replaced with #if 0, the code works as expected.
Could anybody point me into the right direction so Foo(o, 456); compiles?
The problem is the conversion operator, which you have the wrong syntax for.
It should be
operator int&() { return val; }

Encapsulating ublas and overloading the const reference to the operator()

Considering the following toy example, where I declare a class which encapsulates ublas from boost libraries:
#include <boost/numeric/ublas/matrix_sparse.hpp>
#include <iostream>
namespace ublas = boost::numeric::ublas;
class UblasEncapsulated {
public:
ublas::compressed_matrix<float>::reference operator()(int i, int j){
std::cout << "Non const reference" << std::endl;
MtrUpdated_ = true;
return mtr_(i, j);
}
ublas::compressed_matrix<float>::const_reference operator()(
int i, int j) const {
std::cout << "Const reference" << std::endl;
return mtr_(i, j);
}
UblasEncapsulated() { MtrUpdated = false; }
private:
ublas::compressed_matrix<float> mtr_(3, 3);
bool MtrUpdated_;
};
int main() {
UblasEncapsulated foo;
foo(2, 0) = 1.0f;
float const foo_float = foo(2, 0);
return 0;
}
I was expecting the output
Non constant reference
Constant reference
But I got
Non constant reference
Non constant reference
What am I doing wrong? How can I properly track when mtr_ could have its values changed?
foo is non-const, so the non-const version of foo.operator() will be called. It doesn't matter how the value it returns is used.
If you really want to know that MtrUpdated_ is only set true if an element is actually assigned to, you will need to use a proxy class:
class UblasEncapsulated {
public:
class proxy {
public:
proxy(UblasEncapsulated* ptr, int i, int j)
: ptr_(ptr), i_(i), j_(j)
{}
proxy& operator=(float f) {
ptr_->MtrUpdated_ = true;
ptr_->mtr_(i_, j_) = f;
return *this;
}
operator float() {
return ptr_->mtr_(i_, j_);
}
private:
UblasEncapsulated* ptr_;
int i_;
int j_;
};
proxy operator()(int i, int j) {
return proxy(this, i, j);
}
ublas::compressed_matrix<float>::const_reference operator() (int i, int j) const {
return mtr_(i, j);
}
UblasEncapsulated()
: mtr_(3, 3),
MtrUpdated_(false)
{}
private:
ublas::compressed_matrix<float> mtr_;
bool MtrUpdated_;
};
Live Demo
Note that you should avoid using a proxy class if you can get away with it since it doesn't play nicely with things like auto or template argument deduction.

passing function as argument in c++

I am trying pass the function as an argument, the Testabc is inherited from MainTest and the function I want to pass is protected function in MainTest class. I do not have the cpp access to the MainTest class which has this protected ReadTestPoint function.
Below is header file where I define the function that is taking the function as an argument.
#include <QObject>
#include <QDebug>
class TestManager
{
public:
TestManager();
~TestManager() {}
int ReadTestPointer(void *dp, unsigned int &val, int (*functioncall)(void *,
unsigned int&));
};
Below is the cpp for the TestManager
#include "testmanager.h"
#include<QDebug>
TestManager::TestManager(){}
int TestManager::ReadTestPointer(void* dp, unsigned int &num, int (*readt)
(void*, unsigned int&))
{
qDebug()<< "Function Pointer working";
int g;
g = (*readt)(dp, num);
return g;
}
The class from where I am making the call:
namespace PackageCore
{
TestAbc::TestAbc() : MainTest(){}
TestAbc::~TestAbc(){}
int TestAbc::Init()
{
// initialization code called once
m_config = reinterpret_cast<Test_BaseClass*>
(GetConfig(Test_BaseClass_INTERFACE_HASH));
return 0;
}
int TestAbc::DeInit()
{
return 0;
}
int TestAbc::Cycle()
{
TestManager m_TestManager;
unsigned int m_trigger;
int (*abc)(void *, unsigned int&) = ReadTestPoint(m_config-
>SHM_B_Trigger_U8, m_trigger);
m_TestManager.ReadTestPointer(m_config->SHM_B_Trigger_U8, m_trigger, abc);
qDebug()<< " getTrigger: " << m_trigger;
return 0;
}
}
But I get the compile time error on this:
C:\test_manager_git\testabc.cpp:39: error: invalid conversion from 'int' to 'int (*)(void*, unsigned int&)' [-fpermissive]
int (*abc)(void *, unsigned int&) = ReadTestPoint(m_config->SHM_B_Trigger_U8, m_trigger);
The MainTest.h is below:
class MainTest : public QObject
{
Q_OBJECT
public:
// Callbacks
virtual int Init() = 0;
virtual int Cycle() = 0;
virtual int DeInit() = 0;
protected:
int ReadTestPoint (void *dp, unsigned int &val);
};
Thanks
First of all, consider using things like std::function instead of rolling your own pointer nightmare. But lets get started...
Basically, in order to call a member function from pointer, you need the function pointer and a member instance. The following code is based on your question code with the added member pointer.
#include <iostream>
class MainTest
{
public:
protected:
int ReadTestPoint (void *dp, unsigned int &val)
{
std::cout << "protected ReadTestPoint called" << std::endl;
return 0;
}
};
class TestManager
{
public:
TestManager() {}
~TestManager() {}
int ReadTestPointer(void *dp, unsigned int &val, MainTest* instance, int (MainTest::*functioncall)(void *, unsigned int&))
{
return (instance->*functioncall)(dp, val);
}
};
class TestAbc : public MainTest
{
public:
void ExecTest()
{
TestManager testManager;
unsigned int tVal;
void* dummy = &tVal;
testManager.ReadTestPointer(dummy, tVal, this, &TestAbc::ReadTestPoint);
}
};
int main(void)
{
TestAbc test;
test.ExecTest();
return 0;
}
If you don't want to restrict yourself to a specific member type, consider using a template function:
class TestManager
{
public:
TestManager() {}
~TestManager() {}
template<typename Fn>
int ReadTestPointer(void *dp, unsigned int &val, Fn functioncall)
{
return functioncall(dp, val);
}
};
It will accept non-member functions and objects that overload the operator() with appropriate parameters and return types.
You can wrap the member function pointer in a Functor object:
template<typename TMember, typename TResult, typename TParam1, typename TParam2>
struct Functor
{
typedef TResult (TMember::*TFn)(TParam1, TParam2);
Functor(TMember* m, TFn func):member(m), fn(func){}
TMember* member;
TFn fn;
TResult operator()(TParam1 p1, TParam2 p2)
{
return (member->*fn)(p1, p2);
}
};
The following example includes a free function call and a member function call:
int FreeFn(void *dp, unsigned int &val)
{
std::cout << "free function called" << std::endl;
return 1;
}
class TestAbc : public MainTest
{
public:
void ExecTest()
{
TestManager testManager;
unsigned int tVal;
void* dummy = &tVal;
testManager.ReadTestPointer(dummy, tVal, Functor<TestAbc, int, void*, unsigned int&>(this, &TestAbc::ReadTestPoint));
testManager.ReadTestPointer(dummy, tVal, FreeFn);
}
};

C++ - How to get structure last member type and a way to access it from existing object?

Is there any way I can get class last member type and possibly some-way to access it from existing object (pointer to class member). I need this for my own implementation of new and delete built-in operators.
Any ideas how can I check this?
What I want to do basically:
struct S
{
int b;
int arr[];
} ;
struct S1
{
double d;
} ;
last_member_of<S1>::type //type of 'S1::d' - 'double'
last_member_of<S>::type //type of 'S::arr' - 'int []'
last_member_of<S>::value // 'S::*' pointing to 'S::arr'
last_member_of<S1>::value // 'S1::*' pointing to 'S1::d'
The idea is that if the last member is flexible array (I know it's not supported officially by ISO C++ but who cares when most compilers do actually support it) - my re-defined operator will be able to allocate/deallocate additional storage for it, automatically invoking all constructors and destructors.
Here's what to do for the technical aspect, assuming POD item type for the array:
struct S
{
int b;
int arr[1];
auto operator new( size_t const size, int const n )
-> void*
{
return ::operator new( size + (n-1)*sizeof( int ) );
}
void operator delete( void* p )
{
::operator delete( p );
}
};
auto main() -> int
{
auto pS = new( 42 ) S;
// USe it.
delete pS;
}
Disclaimer: code not touched by compiler's hands.
For a general facility, just generalize this. E.g. you can pass the item type of the flexible array as template argument. There's no need to automate just about everything: explicit is good, implicit is bad.
Having said all this, for the practical, just use a std::vector in there.
Addendum:
The OP asked for a direct solution, and I had time to code one up. Well, except that I have not addressed the issue of constructor arguments for the non-array part, or in general for the array items, or const accessors. Hint to the OP about arguments: std::forward is your friend.
Again, all that this buys wrt. using a std::vector is
A particular known memory layout, e.g. to suit some existing C function.
A single dynamic allocation.
#include <iostream>
#include <functional> // std::function
#include <memory> // std::unique_ptr, std::default_delete
#include <new> // std::operator new( size_t, void* )
#include <stddef.h> // size_t
#include <stdexcept> // std::exception, std::runtime_error
#include <stdlib.h> // EXIT_FAILURE, EXIT_SUCCESS
#include <string> // std::string
namespace cppx {
using std::function;
using std::string;
using std::unique_ptr;
using std::runtime_error;
auto fail( string const& s ) -> bool { throw runtime_error( s ); }
class Non_copyable
{
private:
using This_class = Non_copyable;
This_class& operator=( This_class const& ) = delete;
Non_copyable( This_class const& ) = delete;
public:
Non_copyable() {}
Non_copyable( This_class&& ) {}
};
template< class Common_data, class Item >
class Flexible_array
: public Non_copyable
{
template< class T > friend class std::default_delete;
private:
union Start_of_array
{
Item first_item;
char dummy;
~Start_of_array() {}
Start_of_array(): dummy() {}
};
int size_;
Common_data data_;
Start_of_array items_;
// Private destructor prevents non-dynamic allocation.
~Flexible_array()
{
for( int i = size_ - 1; i >= 0; --i )
{
p_item( i )->~Item();
}
}
Flexible_array( int const size ): size_( size ) {}
// Private allocation function prevents client code dynamic allocation.
// It also servers the purpose of allocating the right size for the array.
static auto operator new( size_t const n_bytes, int const n )
-> void*
{ return ::operator new( n_bytes + (n - 1)*sizeof( Item ) ); }
// Matching operator delete for the case where constructor throws.
static void operator delete( void* const p, int )
{ ::operator delete( p ); }
// General operator delete.
static void operator delete( void* const p )
{ ::operator delete( p ); }
public:
auto size() const -> int { return size_; }
auto data() -> Common_data& { return data_; }
auto p_item( int const i ) -> Item* { return &items_.first_item + i; }
auto item( int const i ) -> Item& { return *p_item( i ); }
void destroy() { delete this; }
static auto create( int const size, function< void( int id, void* p_storage ) > construct )
-> Flexible_array*
{
unique_ptr< Flexible_array > p_flex{ new( size ) Flexible_array( size ) };
for( int i = 0; i < size; ++i )
{
try
{
construct( i, p_flex->p_item( i ) );
}
catch( ... )
{
p_flex->size_ = i;
throw;
}
}
return p_flex.release();
}
static auto create( int const size, Item const& default_value )
-> Flexible_array*
{ return create( size, [&]( int, void* p ) { ::new( p ) Item( default_value ); } ); }
static auto create( int const size )
-> Flexible_array*
{ return create( size, [&]( int, void* p ) { ::new( p ) Item(); } ); }
};
} // namespace cppx
struct X
{
int id;
~X() { std::clog << "X " << id << " destroyed\n"; }
X( int const i )
: id( i )
{
if( i == 5 ) { cppx::fail( "Intentional failure of X 5 construction" ); }
std::clog << "X " << id << " created\n";
}
X( X const& other )
: id( other.id )
{
std::clog << "X " << id << " copy-created\n";
}
};
auto main() -> int
{
using namespace std;
try
{
using Flex = cppx::Flexible_array< int, X >;
unique_ptr<Flex> const p{ Flex::create(
7 ,
X( 42 ) // or e.g. "[]( int i, void* p ) { ::new( p ) X( i ); }"
) };
return EXIT_SUCCESS;
}
catch( exception const& x )
{
cerr << "!" << x.what() << "\n";
}
return EXIT_FAILURE;
}
It is impossible to get the last struct member automatically.
It's easy to understand this, if you realize that the end of a struct may have padding: there is simply no way to know if the end is just padding or a value:
#include <cstdint>
#include <cstddef>
struct A1 {
uint32_t a;
uint8_t x1;
}; // 3 bytes padding at the end
struct A2 {
uint32_t a;
uint8_t x1;
uint8_t x2;
}; // 2 bytes padding at the end
struct A3 {
uint32_t a;
uint8_t x1;
uint8_t x2;
uint8_t x3;
}; // 1 byte padding at the end
struct A4 {
uint32_t a;
uint8_t x1;
uint8_t x2;
uint8_t x3;
uint8_t x4;
}; // no padding
int main()
{
static_assert(sizeof(A1) == 8);
static_assert(sizeof(A2) == 8);
static_assert(sizeof(A3) == 8);
static_assert(sizeof(A4) == 8);
static_assert(offsetof(A1, x1) == 4);
static_assert(offsetof(A2, x2) == 5);
static_assert(offsetof(A3, x3) == 6);
static_assert(offsetof(A4, x4) == 7);
}

c++: Performance increase on non-template delegate class

This is a simple delegate class that only works for methods of the format void ClassType::MethodType( InputType& ), but can easily be expanded to more generic functions, not shown simply because it would be too large.
class Delegate
{
public:
Delegate( void ) : Object( NULL ), Argument( NULL ) { }
virtual ~Delegate( void ) { }
template <class ClassType, class InputType, void (ClassType::*MethodType)( InputType )>
void Create( ClassType* SetObject, void* SetArgument = NULL )
{
Object = SetObject;
Argument = SetArgument;
StaticCall = &CallMethod<ClassType, InputType, MethodType>;
}
template <class InputType>
inline void operator()( InputType InputValue ) const
{
(*StaticCall)( Object, static_cast<void*>(InputValue) );
}
inline void operator()( void ) const
{
(*StaticCall)( Object, Argument );
}
protected:
typedef void (*FunctionCallType)( void*, void* );
void* Object;
void* Argument;
FunctionCallType StaticCall;
private:
template <class ClassType, class InputType, void (ClassType::*MethodType)( InputType )>
static inline void CallMethod( void* SetObject, void* PassArgument )
{
(static_cast<ClassType*>( SetObject )->*MethodType)( static_cast<InputType>(PassArgument) );
}
};
It's flexible and can be used to pool callback classes, but one problem I have with it is that so far it's on par with (or even slower when used in large vectors like I plan to) than a virtual call if it's used as a base class. I'm looking for any suggestions on how to increase performance since I'm out of ideas, even if it affects functionality.
The simplest performance measuring code I used (with -O3) was:
class VirtualBase
{
public:
virtual void TestCall( int* Data ) {}
};
class VirtualTest : public VirtualBase
{
public:
VirtualTest() : Value(0) {}
void TestCall( int* Data )
{
Value += *Data;
}
private:
int Value;
};
class DelTest : public Delegate
{
public:
DelTest() : Value(0)
{
Create<DelTest, int*, &DelTest::TestCall>( this );
}
void TestCall( int* Data )
{
Value += *Data;
}
private:
int Value;
};
int main( int argc, char **argv )
{
clock_t start;
int Value = 1;
VirtualBase* NewBase = new VirtualTest;
start = clock();
for( size_t Index = 0; Index < 1000000000; ++Index )
{
NewBase->TestCall( &Value );
}
delete NewBase;
std::cout << (( std::clock() - start ) / (double)CLOCKS_PER_SEC) << std::endl;
Delegate* NewDBase = new DelTest;
start = clock();
for( size_t Index = 0; Index < 1000000000; ++Index )
{
NewDBase->operator()( &Value );
}
delete NewDBase;
std::cout << (( std::clock() - start ) / (double)CLOCKS_PER_SEC) << std::endl;
return 0;
}
I should mention that I'd like the class to stay non-template, as it makes classes using callbacks to anything easy to iterate through in a single vector.
You might want to look at this Lightweight Generic C++ Callbacks article on CodeProject
Some of the code from the linked article, showing the use of a function template to do the forwarding:
template<typename R, typename P1, typename P2>
class Callback
{
public:
typedef R (*FuncType)(void*, P1, P2);
Callback() : func(0), obj(0) {}
Callback(FuncType f, void* o) : func(f), obj(o) {}
R operator()(P1 a1, P2 a2)
{
return (*func)(obj, a1, a2);
}
private:
FuncType func;
void* obj;
};
template<typename R, class T, typename P1, typename P2, R (T::*Func)(P1, P2)>
R Wrapper(void* o, P1 a1, P2 a2)
{
return (static_cast<T*>(o)->*Func)(a1, a2);
}
class Foo
{
public:
float Average(int n1, int n2)
{
return (n1 + n2) / 2.0f;
}
};
float Calculate(int n1, int n2, Callback<float, int, int> callback)
{
return callback(n1, n2);
}
int main()
{
Foo f;
Callback<float, int, int> cb
(&Wrapper<float, Foo, int, int, &Foo::Average>, &f);
float result = Calculate(50, 100, cb);
// result == 75.0f
return 0;
}
There is also a great write up on stackoverflow here which will give you better insight.