可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
One of my colleagues has recently said that the above statement is not type safe and I should use something else as you need as much type safe structures as possible to reduce the amount of possible bugs.
Whilst I agree on being type safe, I'm a little confused as this is the type of code in question (only the contents and length of data[] is modified)
unsigned char data[] = {1,2,3,4,5}; int data_len = sizeof(data) / sizeof(data[0]);
Where is the part that is not type safe?
Needless to say, other than the comment, the colleague will not explain further.
PS: This is used to copy initialisation data into a class from the constructor, no C++11 compiler exists here, so we can't use std::array or other fancy array initialisation. techniques.
回答1:
Maybe your colleague meant that using this expression with pointers will give an unexpected result. This mistake is made very often by beginners. For example
void f( unsigned char data[] ) { int data_len = sizeof(data) / sizeof(data[0]); //... } //... unsigned char data[] = {1,2,3,4,5}; f( data );
So in general case it would be more safely to use a template function instead of the expression. For example
template inline size_t size( const T ( & )[N] ) { return N; }
Take into account that there is template structure std::extent
in C++ 11 that can be used to get the size of a dimension.
For example
int a[2][4][6]; std::cout ::value ::value ::value
回答2:
One possible problem is that if data is created on the heap with new, you won't get the length, instead some value related to the length of a pointer on the system you are on.
char* data = new char[5]; //sizeof(data) is dependent on system
回答3:
sizeof data / sizeof *data
is perfectly fine and typesafe. But you must be able to guaranted that:
- You really feed it an array, not a pointer
- Said array is not zero length
- Up to C99 at least , int[0] would be a constraint violation and thus must be diagnosed. Many compilers allow it as an extension.
- Up to C++13 at least, the same holds true for C++.
You can get a diagnostic if you didn't provide an array by using templates:
template inline size_t elements_of(const T&[n]) { return n; }
回答4:
#include void fun(int arr[]) { /* sizeof cannot be used here to get number of elements in array*/ int arr_size = sizeof(arr)/sizeof(arr[0]); /* incorrect use of sizeof*/ } int main() { int arr[4] = {0, 0 ,0, 0}; fun(arr); return 0; }
In C, array parameters decay to pointers. So the expression sizeof(arr)/sizeof(arr[0])
becomes sizeof(int*)/sizeof(int)
which results in 1 for IA32 machine.
Therefore, sizeof
should not be used to get number of elements in such cases. A separate parameter for array size (or length) must be passed to fun()
. So the corrected program for printing the numbers is:
#include void fun(int arr[], size_t arr_size) { int i; for (i = 0; i