I'm using Cppcheck's Python API and --dump flag to develop some custom rules. I need the sizes of class types. I tried editing the source code to get the size of classes. Specifically in ValueType::dump()
I added : if (typeScope != nullptr && typeScope->definedType != nullptr) ret << " valueType-size=\"" << typeScope->definedType->sizeOf << '\"';
but it always returns 0 as value in the dump. Additionally, in Tokenizer::dump()
I added: out << " size=\"" << sizeOfType(tok) << '\"';
but it returns 0 too. Is there a way to get the size of classes in dump?
I'm currently using a work around where I get the sizes of types from platform tag from dump then I get the size of classes by checking its member variables however platform tag doesn't include sizes of types float,double,long double and bool which is inconvenient.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
it sounds good to add the size of types to the dump.
To start with.. adding sizes of float/double/long double and bool to the platform should be pretty straight forward. I did not know that was missing. I wonder.. could you look into that and send us a PR that makes this?
adding the size of struct/classes .. I guess we need to look at that a bit. I guess there is some lacking support for that in Cppcheck. it's rarelly needed by checkers. But it would be preferable to do it inside Cppcheck. However I believe Cppcheck cannot calculate it exactly because we don't know what exact padding the compiler will use and there are also often plenty of missing type info.
Typically checkers don't need an exact value, it's enough that it is consistent. i.e. if you write memset(foo, 0, sizeof(*foo)) .. we can determine that there is not buffer overflow without an exact value.. as long as Cppcheck reports consistent sizes for 1st and 3rd arguments.
I have the feeling that we calculate the sizes of structs somewhere but can't point out the code directly off the top of my head.
Last edit: Daniel Marjamäki 2020-12-03
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I wonder.. could you look into that and send us a PR that makes this?
Unfortunately. I'm not allowed, nor able to, push any kind of code to web from work and I don't have enough free time to do on my own.
However I believe Cppcheck cannot calculate it exactly because we don't know what exact padding the compiler will use and there are also often plenty of missing type info.
What do you mean by type info exactly?
Last edit: samed 2020-12-03
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
To give a little bit context my goal is to create a rule to suggest passing function parameters by reference if they're greater than size X.
For padding, I think used compiler can be taken as an input and compiler specific preprocessor directives can be handled case by case and for unhandled ones maximum padding can be assumed.
I guess by type info you're talking about vtables and possibly RTTI overhead (I don't know if there's any though). Although it won't be 100% accurate, I think a good estimation can be made by let's say adding 1 vtable pointer for each distinct base class. No idea on RTTI though.
Last edit: samed 2020-12-04
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I suggest we skip padding, vtables and rtti, .. we cannot do that properly and then it's better to leave it out. I do not know how vtables and rtti look neither.
We have a check to pass parameters by const reference in cppcheck.. and that uses this limit for classes:
I suggest we skip padding, vtables and rtti, .. we cannot do that properly and then it's better to leave it out. I do not know how vtables and rtti look neither.
I'm fine with that. We have to make do with estimation anyways since compilers can change any time.
So I have the feeling we have tried to solve your problem in cppcheck already. Doesn't it work well?
It never threw an error though. I've tried some random code and compiles with MSVC. sizeof() returns 20 bytes (160 bits). Pointer size is 64 bits so it should throw an error, right?
Last edit: samed 2020-12-04
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
#include<iostream>usingnamespacestd;//Shouldbe64bitsclassBase {
int*i; //Should be 64bits
};//Shouldbe128bitsclassDerived : Base {
int*j; //Should be 64bits
};//Shouldbe192bitsclassLargeClass {
DerivedderivedObj; //Should be 128bitschar*x;//Should be 64bits
};voidf(LargeClasslargeArg){
//...
}
intmain()
{
LargeClasslargeObj;f(largeObj);return0;
}
Currently I'm home and my computer doesn't have a compiler or Cppcheck. Anyways, pointers are 64bit at my work computer. So, this wouldn't report error.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I've tried again today and Cppcheck throws an error for large classes. The thing is, it only works on function definitions. I guess I didn't define the function last time at work. However one small problem: It doesn't throw error if variable is unnamed.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi,
I'm using Cppcheck's Python API and --dump flag to develop some custom rules. I need the sizes of class types. I tried editing the source code to get the size of classes. Specifically in
ValueType::dump()
I added :
if (typeScope != nullptr && typeScope->definedType != nullptr)
ret << " valueType-size=\"" << typeScope->definedType->sizeOf << '\"';
but it always returns 0 as value in the dump. Additionally, in
Tokenizer::dump()
I added:
out << " size=\"" << sizeOfType(tok) << '\"';
but it returns 0 too. Is there a way to get the size of classes in dump?
I'm currently using a work around where I get the sizes of types from
platform
tag from dump then I get the size of classes by checking its member variables howeverplatform
tag doesn't include sizes of typesfloat
,double
,long double
andbool
which is inconvenient.it sounds good to add the size of types to the dump.
To start with.. adding sizes of float/double/long double and bool to the platform should be pretty straight forward. I did not know that was missing. I wonder.. could you look into that and send us a PR that makes this?
adding the size of struct/classes .. I guess we need to look at that a bit. I guess there is some lacking support for that in Cppcheck. it's rarelly needed by checkers. But it would be preferable to do it inside Cppcheck. However I believe Cppcheck cannot calculate it exactly because we don't know what exact padding the compiler will use and there are also often plenty of missing type info.
Typically checkers don't need an exact value, it's enough that it is consistent. i.e. if you write
memset(foo, 0, sizeof(*foo))
.. we can determine that there is not buffer overflow without an exact value.. as long as Cppcheck reports consistent sizes for 1st and 3rd arguments.I have the feeling that we calculate the sizes of structs somewhere but can't point out the code directly off the top of my head.
Last edit: Daniel Marjamäki 2020-12-03
Unfortunately. I'm not allowed, nor able to, push any kind of code to web from work and I don't have enough free time to do on my own.
What do you mean by type info exactly?
Last edit: samed 2020-12-03
To give a little bit context my goal is to create a rule to suggest passing function parameters by reference if they're greater than size X.
For padding, I think used compiler can be taken as an input and compiler specific preprocessor directives can be handled case by case and for unhandled ones maximum padding can be assumed.
I guess by type info you're talking about vtables and possibly RTTI overhead (I don't know if there's any though). Although it won't be 100% accurate, I think a good estimation can be made by let's say adding 1 vtable pointer for each distinct base class. No idea on RTTI though.
Last edit: samed 2020-12-04
Thanks that helps imho.
I suggest we skip padding, vtables and rtti, .. we cannot do that properly and then it's better to leave it out. I do not know how vtables and rtti look neither.
We have a check to pass parameters by const reference in cppcheck.. and that uses this limit for classes:
For information it's in
CheckOther::checkPassByReference()
in cppcheck/lib/checkother.cpp.So I have the feeling we have tried to solve your problem in cppcheck already. Doesn't it work well?
Last edit: Daniel Marjamäki 2020-12-04
I'm fine with that. We have to make do with estimation anyways since compilers can change any time.
It never threw an error though. I've tried some random code and compiles with MSVC.
sizeof()
returns20 bytes
(160 bits). Pointer size is64 bits
so it should throw an error, right?Last edit: samed 2020-12-04
can you share a minimal code sample?
Currently I'm home and my computer doesn't have a compiler or Cppcheck. Anyways, pointers are 64bit at my work computer. So, this wouldn't report error.
ok thanks. Cppcheck output:
ok I assume you saw a case before that did not work.. if/when you see that feel free to post it here..
Last edit: Daniel Marjamäki 2020-12-04
Interesting. What flags and what version were you using? I was using 2.1, maybe that's the problem?
Just:
cppcheck --enable=style constref.cpp
I do not have cppcheck-2.1 locally but both cppcheck-2.0 and cppcheck-2.2 warns.
I've tried again today and Cppcheck throws an error for large classes. The thing is, it only works on function definitions. I guess I didn't define the function last time at work. However one small problem: It doesn't throw error if variable is unnamed.