C++:函数arg char** 与char*[] 不同 [英] c++: function arg char** is not the same as char*[]
问题描述
我正在使用 g++.我正在使用具有 main(int,char**)
的代码,重命名以便我可以调用它.我查看了 我应该使用 char** argv 还是 char* C 中的 argv[]?,其中 char**
相当于 char* []
.这在 c++ 函数调用中似乎不是真的.例如:
I am using g++. I am using code that had a main(int,char**)
, renamed so I can call it. I looked at Should I use char** argv or char* argv[] in C?, where char**
is said to be equivalent to char* []
. This does not appear to be true in c++ function calls. For example:
void f1(char** p){;}
void f2(char* p[]){
f1(p);
//...`
}
失败,编译器抱怨无法将 char (*)[]
转换为 char**
..." 引用我想说数组被转换为调用的指针,但情况似乎并非如此:
fails with the compiler complaining "cannot convert char (*)[]
to char**
..." The references I look to say that arrays are converted to pointers for the call, but this does not seem to be the case as:
void f3(char* [] p);
char caa[16][16];
f3(caa);
也失败了.我曾假设只要间接级别相同(例如 char*** ptr
和 char[][][] carray
),类型就可以互换.
also fails. I had assumed that as long as the levels of indirection were the same (e.g. char*** ptr
and char[][][] carray
) the types were interchangeable.
有人可以提供我可以查看的参考资料来澄清这些问题吗?
Can someone provide a reference I can review that clarifies these issues?
谢谢.
推荐答案
这在 C++ 中仍然适用.如果您的编译器如您在第一种情况下所描述的那样抱怨,则它不符合要求.
This still holds true in C++. If your compiler complains as you describe for your first case, it is non-conformant.
要解释您的第二种情况,了解实际发生的情况很重要.数组类型的表达式可以隐式转换为相应的指针类型,即:T[n]
-> T*
.但是,如果 T
本身是一个数组,则不会对这种情况进行特殊处理,并且数组到指针的衰减不会传播.所以 T*[n]
衰减到 T**
,但是 T[x][y]
只会衰减到 T[y]*
,不再赘述.
To explain your second case, it is important to understand what actually happens. An expression of array type is implicitly convertible to a corresponding pointer type, i.e.: T[n]
-> T*
. However, if T
itself is an array, this case isn't treated specially, and array-to-pointer decay does not propagate. So T*[n]
decays to T**
, but T[x][y]
will only decay to T[y]*
, and no further.
从实现的角度来看,这是有道理的,因为如果允许的话,进一步衰减会得到 T**
,它是指向指针的指针;而 2D C 数组不是作为锯齿状数组实现的(即指向数组的指针数组)——它们形成了一个连续的内存块.因此,在数组内部"没有 T*
可以获取一个地址来为您提供 T**
.对于允许的情况,典型的实现简单地将数组的地址作为一个整体并将其转换为指向单个元素的指针类型(当所有类型的底层指针表示相同时,通常情况下,这种转换是运行时无操作).
From implementation perspective this makes sense, because decaying further, if allowed, would give T**
, which is pointer to pointer; whereas 2D C arrays aren't implemented as jagged arrays (i.e. array of pointers to arrays) - they form a single contiguous memory block. So, there's no T*
"inside" the array to take an address of to give you a T**
. For the allowed cases, a typical implementation simply takes the address of the array as a whole and converts it to type of pointer to single element (when underlying pointer representation is the same for all types, as is usually the case, this convertion is a no-op at run time).
这里的规范参考是ISO C++03, 4.2[conv.array]/1:
The normative reference here is ISO C++03, 4.2[conv.array]/1:
N T 数组"或T 的未知边界数组"类型的左值或右值可以转换为指向 T 的指针"类型的右值.结果是指向数组第一个元素的指针.
An lvalue or rvalue of type "array of N T" or "array of unknown bound of T" can be converted to an rvalue of type "pointer to T." The result is a pointer to the first element of the array.
这篇关于C++:函数arg char** 与char*[] 不同的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!