tldr
Is there a way, to statically detect error in following code?
struct Foo
{
operator const int*()
{
return &data;
}
int data;
};
int main()
{
Foo f;
delete f;
}
since there is a conversion from Foo to void* containing just one user defined conversion, it is actually allowed to call delete
on f
.
longer story
in our codebase, there was a really stupid way of deserialize strings, in pseudocode
char * buff = bar.loadString();
use buff;
delete buff;
the way was changed, to one templated load function, so now deserialize looks like
bar.load(m_IntMember);
bar.load(m_StringMember);
but all occurrences (there was a lot of them) of loadString
had to be manually changed like this:
string buff;
bar.load(buff);
use buff;
we all know what human error can cause, so there are places, where code was wrongly modified like
string buff;
bar.load(buff);
use buff;
delete buff; //notice the delete
since we are using a bit non-standard implementation of string
it actually has a overloaded const char * operator
, which can be casted to void*
which can be deleted...
I would like to catch all of these errors at compile time (we have custom high performance allocators, so at runtime, it is easy to corrupt memory without any runtime error)
I cannot declare global delete operator accepting const char*
I cannot temporarily delete delete operator from string
because it is heavily used, so it is unable to compile without it (I cannot "filter out" described error from all errors, because msvc stops compilation when reaching certain amount of errors)
what can I do?
This seems to do it:
#include <iostream>
struct Foo
{
Foo() : data(42) {}
operator const int*()
{
return &data;
}
int data;
struct AmbiguousPointerConversion {};
private: operator AmbiguousPointerConversion *() {
throw "hi";
}
};
int main()
{
Foo f;
const int *p = f;
std::cout << *p << '\n';
delete f;
}
Compiling this with g++ gives me:
try.cc: In function ‘int main()’:
try.cc:25:12: error: ambiguous default type conversion from ‘Foo’
delete f;
^
try.cc:25:12: note: candidate conversions include ‘Foo::operator const int*()’ and ‘Foo::operator Foo::AmbiguousPointerConversion*()’
try.cc:25:12: error: type ‘struct Foo’ argument given to ‘delete’, expected pointer
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With