根据n4640中的5.2.2/4"函数调用"(n4659中的8.2.2/4),在调用者的上下文中创建和销毁函数参数.并且允许实现将函数参数的破坏延迟到封闭的完整表达式的末尾(作为实现定义的特征).请注意,选择不是未指定的,而是实现定义的.
(目前还不完全清楚这与3.3.3"块范围"(n4659中的6.3.3)是否一致,这似乎意味着函数参数具有块范围,然后是3.7.3"自动存储持续时间"(6.7.3)在n4659)中,它表示块作用域变量的存储一直存在,直到它们被创建的块出现.但是我们假设我在措辞中缺少/误解了一些内容.显然现在函数参数将有自己的范围)
据我所知,ABI要求GCC和Clang将函数参数的销毁延迟到完全表达式的末尾,即这是这些编译器的实现定义行为.我猜想在类似的实现中,只要在调用表达式中使用这些引用/指针,就可以返回对函数参数的引用/指针.
但是,以下示例在GCC中的段错误并且在Clang中正常工作
#include <iostream>
#include <string>
std::string &foo(std::string s)
{
return s;
}
int main()
{
std::cout << foo("Hello World!") << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
两个编译器都发出关于返回对局部变量的引用的警告,这在这里是完全合适的.快速检查生成的代码表明,两个编译器确实将参数的破坏延迟到表达式的末尾.但是,GCC仍故意返回"null引用" foo,导致崩溃.与此同时,Clang表现为"按预期",返回对其参数的引用,该参数的s存活时间足以产生预期的输出.
(简单来说,GCC在这种情况下很容易愚弄
std::string &foo(std::string s)
{
std::string *p = &s;
return *p;
}
Run Code Online (Sandbox Code Playgroud)
它修复了GCC下的段错误.)
在这种情况下GCC的行为是否合理,假设它保证参数的"晚期"破坏?我是否遗漏了标准中的其他段落,即返回对函数参数的引用始终未定义,即使它们的生命周期是由实现扩展的?
在其中一个C++程序中,我看到了一个函数原型: int Classifier::command(int argc, const char*const* argv)
什么const char*const* argv意思?它是一样的const char* argv[]吗?是否const char** argv也意味着相同?
int main()
{
char *x = "HelloWorld";
char y[] = "HelloWorld";
x[0] = 'Z';
//y[0] = 'M';
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在上面的程序中,HelloWorld将处于只读部分(即字符串表).x将指向该只读部分,因此尝试修改该值将是未定义的行为.
但是y将在堆栈中分配HelloWorld并将被复制到该内存中.所以修改y将正常工作.字符串文字:指针与字符数组
这是我的问题:
在下面的程序中,都char *arr和char arr[]使段错误,如果内容被修改.
void function(char arr[])
//void function(char *arr)
{
arr[0] = 'X';
}
int main()
{
function("MyString");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
请分享您的知识.
我知道星号在Python中的函数定义中是什么意思.
不过,我经常会看到使用参数调用函数的星号:
def foo(*args, **kwargs):
first_func(args, kwargs)
second_func(*args, **kwargs)
Run Code Online (Sandbox Code Playgroud)
第一个和第二个函数调用有什么区别?
功能原型
void foo(int n, int a[][]);
Run Code Online (Sandbox Code Playgroud)
给出了关于不完整类型的错误
void foo(int n, int (*a)[]);
Run Code Online (Sandbox Code Playgroud)
编译.根据衰减规则int a[][]相当于int (*a)[]在这种情况下,因此也int (*a)[]应该给出关于不完整类型的错误,但GCC似乎接受它.有什么我想念的吗?这可能是一个GCC错误,但我没有发现任何与之相关的内容.
有一种情况,我想收集 JSON 中一个键的路径的所有节点名称。考虑条件:JSON 数组索引“0”、“1”也是允许的,但是很容易忘记引号,这会导致在取消引用时崩溃。所以我希望编译器拒绝这种参数。例子:
#include <vector>
#include <iostream>
int func(const std::vector<const char*>& pin) {
return pin.size();
}
int main() {
// {"aname", "3", "path", "0"} wanted but this still compile
std::cout << func({"aname", "3", "path", 0}) << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
参考如何避免对非构造函数进行隐式转换?我尝试了以下内容:
#include <vector>
#include <iostream>
int func(const std::vector<const char*>& pin) {
return pin.size();
}
int func(const std::vector<int>& pin) = delete;
// or
/* I want to describe only pointer type parameter is allowed as element,
but parameter of any …Run Code Online (Sandbox Code Playgroud) 根据 ISO C(任何版本),指定零大小的数组参数是否有效?
\n该标准似乎含糊不清。虽然很明显零大小的数组是无效的,但数组函数参数很特殊:
\nC23::6.7.6.3/6:
\n\n\n将参数声明为“类型数组”应调整为“指向类型的限定指针”,其中类型限定符(如果有)是在数组类型派生的 [ 和 ] 内指定的限定符。如果\n关键字 static 也出现在数组类型派生的 [ 和 ] 中,则对于每次调用该函数,\n相应实际参数的值应提供对数组的第一个\n元素的访问,\n至少为由 size 表达式指定的许多元素。\n
\n
只要您不使用static,之间指定的大小[]就会被有效忽略。据我了解引用的段落,编译器根本不允许对指针做出任何假设。
那么,下面的代码应该是符合要求的,对吧?
\nvoid h(char *start, char past_end[0]);\n\n#define size 100\nvoid j(void)\n{\n char dst[size];\n h(dst, dst+size);\n}\nRun Code Online (Sandbox Code Playgroud)\n我使用past_end[0]作为指向末尾一位的哨兵指针(而不是大小;在某些情况下它更舒服)。清楚[0]地表明这是一个过去的结束,而不是实际的结束,作为一个指针,读者可能会感到困惑。结束将被标记为end[1]为清楚起见,
GCC 认为它不符合:
\n$ gcc -Wall -Wextra -Wpedantic -pedantic-errors -std=c17 -S ap.c \nap.c:1:26: error: ISO C forbids zero-size array \xe2\x80\x98past_end\xe2\x80\x99 [-Wpedantic]\n 1 | void h(char *start, char …Run Code Online (Sandbox Code Playgroud) 考虑方法
functionA (double[] arg)
Run Code Online (Sandbox Code Playgroud)
我想传递一个内联的双数组,比如
functionA({1.9,2.8})
Run Code Online (Sandbox Code Playgroud)
而不是先创建一个数组然后传递它,就像
double var[] = {1.0,2.0};
functionA(var);
Run Code Online (Sandbox Code Playgroud)
这可能用C++吗?听起来很简单,但无论如何我无法找到关于我的问题的提示,这让我怀疑:).
我正在研究数据结构(列表,堆栈,队列),这部分代码让我感到困惑.
ListNode( const Object& theElement = Object(), ListNode * node = NULL);
template<class Object>
ListNode<Object>::ListNode( const Object& theElement, ListNode<Object> * node) {
element = theElement;
next = node;
}
Run Code Online (Sandbox Code Playgroud)
Object()电话呢?我有一个看起来像这样的函数:
function global:Test-Multi {
Param([string]$Suite)
& perl -S "$Suite\runall.pl" -procs:$env:NUMBER_OF_PROCESSORS
}
Run Code Online (Sandbox Code Playgroud)
我想允许用户为Test-Multi指定更多参数,并将它们直接传递给底层的旧perl脚本.
powershell是否提供了一种机制来为此目的允许额外的可变行为?
c++ ×5
arrays ×3
c ×3
gcc ×2
pointers ×2
destruction ×1
function ×1
lifetime ×1
parameters ×1
powershell ×1
python ×1
scope ×1