Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/61.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 为什么编译器不发出获取寄存器操作数地址的诊断?_C - Fatal编程技术网

C 为什么编译器不发出获取寄存器操作数地址的诊断?

C 为什么编译器不发出获取寄存器操作数地址的诊断?,c,C,我知道引用注册变量的地址会导致编译错误 int main() { register int i = 10; int *a = &i; printf("%d", *a); getchar(); return 0; } 正如所料,这在使用gcc时会导致编译器错误,因为引用了注册变量i的地址 那么,下面的代码做了类似的事情,怎么会没有错误呢 #include<stdio.h> int *NEXT(register int i) {

我知道引用注册变量的地址会导致编译错误

int main()
{
    register int i = 10;
    int *a = &i;
    printf("%d", *a);
    getchar();
    return 0;
}
正如所料,这在使用
gcc
时会导致编译器错误,因为引用了注册变量
i
的地址

那么,下面的代码做了类似的事情,怎么会没有错误呢

#include<stdio.h>
int *NEXT(register int i)
{
    int *ipt;
    ipt = &i;
    ipt++;
    return ipt;
}
main ()
{
    int j=2;
    printf("%d",(NEXT(j)));
}
#包括
int*NEXT(寄存器int i)
{
int*ipt;
ipt=&i;
ipt++;
返回ipt;
}
主要()
{
int j=2;
printf(“%d”,(NEXT(j));
}
编辑:我的gcc版本在

i686-apple-darwin11-llvm-gcc-4.2(gcc)4.2.1(基于苹果公司的构建5658)(llvm构建2335.15.00) 版权所有(C)2007免费软件基金会。 这是自由软件;有关复制条件,请参见源。没有
担保甚至对于适销性或特定用途的适用性也不适用。

编译器可以自由忽略任何寄存器指令,但获取此类变量的地址仍然是非法的

我确信,在任何情况下,将寄存器变量作为函数参数传递都会被忽略,除非函数是
inline
d,因为堆栈必须由函数参数填充:以及一个宽容的编译器,比如您正在使用的编译器;将以其地址为准

我想知道这种行为是否是标准的。我将投票支持一位肯定知道答案的专家给出的任何答案

ipt = &i;
您正在获取
寄存器
对象的地址。编译器必须发出警告,如果需要,可以停止编译。这实际上意味着,如果您的编译器没有发出警告,编译器就不能假装是一个合格的C编译器(C99,5.1.1.3p1)

除此之外:

printf("%d",(NEXT(j)));

d
转换说明符需要一个
int
,但您正在传递一个
int*

如果您的报告是准确的,这可能是由于编译器中的错误,或者可能是由于编译器不符合标准C的允许编译模式



根据C 2011 5.1.1.3,当违反约束时,C实现必须生成诊断。根据6.5.3.2,一个约束条件是
&
的操作数不得已用寄存器声明。因此,在这种情况下,一致性编译器不能随意忽略错误;它必须产生一个与OP的问题无关的诊断。

@FredrikPihl。如果你是说2。示例不给出错误,我会认为它是GCC错误。(我尝试过的所有gcc安装都失败了。)您使用的是什么版本的gcc?我得到:
register.c:5:5:错误:使用gcc版本4.7.2(Debian 4.7.2-5)请求的寄存器变量“I”的地址。@Havenard:我投了赞成票以抵消您不正确的反对票。“register”关键字的文档没有回答这个问题。不,它不能忽略
register
。如果使用该变量声明的变量的地址被占用,则这是一个约束冲突,需要一条诊断消息。如果您将register作为函数参数之一,是否确实会出现这种情况?我想我在这里是正确的;尤其是对于较旧的linux编译器。但我很高兴在这一点上被告知我错了。许多体系结构在寄存器中传递参数。@Bathsheba要求C编译器不允许您获取寄存器变量的地址(是的,即使编译器实际上没有将变量放入寄存器中).@SamuelEdwinWard:参数是否通过cpu寄存器传递与对象是否具有
寄存器
存储无关。@ouah:即使您的答案包含正确的语句,您认为正确的语句必须被表决为向上还是不被表决为向下?投票准则说的是判断有用性,而不是真实性或正确性。这个答案并没有回答这个问题,这就是为什么编译器在显然应该生成诊断时不生成诊断。这个“答案”并没有给出任何有用的信息。@EricPostFischil答案是:如果编译器没有发出正确的诊断,那么它就不是一个符合C标准的编译器。@ouah:那么写一个答案说明这一点。因为它不在这个答案中,所以这个答案仍然没有用处。@EricPostFischil我的答案被反对票突然打断了,但我可以增加这个精度。@JimBalter:我认为这是ouah浏览器中的JavaScript实现有问题。我在mac上使用的是gcc。GCC -版本给了我这个I68 6 Apple DARWIN 1LLVM GCC-4.2(GCC)4.2.1(基于Apple Inc. Bube 5658)(LLVM Bu建323 5.1500)版权(C)2007免费软件基金会,这是免费软件;有关复制条件,请参见源。没有担保;甚至不是为了适销性或适合某一特定目的。@richi_18007:这是一个相当古老的编译器。我拥有的最旧版本稍新,也是4.2.1版本,但版本为5666。它报告获取声明的参数
寄存器的地址时出错。较新的Apple编译器,包括Apple clang 4.0和Apple LLVM 5.0,也报告了一个错误。我只能假设这是一个暂时的错误,或者编译器编译的源文件与您想象的不同。不过,它现在给了我一个错误。我猜这是一个暂时的错误,或者我编译了错误的源文件。