English 中文(简体)
视觉C++为什么会警告从无效的纸张中渗入到C,而不是C++。
原标题:Why does Visual C++ warn on implicit cast from const void ** to void * in C, but not in C++?

Summary

微软视频演播室的C/C++汇编者发出警告C4090。 当一项C方案试图将点人转换为const 数据(如const void **const char **(尽管这种类型实际上不是const的点)。 更奇怪的是,同一汇编者沉默地接受与C++相同的编码。

这种不一致的原因何在,视觉演播室(与其他汇编者一样)为什么在暗中将点名改为点码(<条码/代码>)变成一个“避免的问题?

Details

I have a C program in which C-strings passed in a variable argument list are read into an array (by a loop in which va_arg is invoked). Since the C-strings are of type const char *, the array that keeps track of them is of type const char **. This array of pointers to strings with const content is itself allocated dynamically (with calloc) and I free it before the function returns (after the C-strings have been processed).

当我用<代码>cl.exe(在微软C++中)汇编该代码时,即使警报水平较低,<代码>免费<>代码>打电话触发了C4090。 自<条码>以来void*,对我说,汇编者照样把const char **改为 void*>。 我为证实这一点创造了一个简单的例子,其中我试图将<条码>const void **改为<条码>,删除*:

/* cast.c - Can a const void** be cast implicitly to void* ? */

int main(void)
{
    const void **p = 0;
    void *q;
    q = p;

    return 0;
}

我随后汇编如下:确认这是引起警告的原因:

>cl cast.c
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.40219.01 for 80x86
Copyright (C) Microsoft Corporation.  All rights reserved.

cast.c
cast.c(7) : warning C4090:  =  : different  const  qualifiers
Microsoft (R) Incremental Linker Version 10.00.40219.01
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:cast.exe
cast.obj

微软 s 关于警告C40的文件 说:

对C方案发出了警告。 在C++方案中,汇编者发行了一个错误:C2440。

这一点是有意义的,因为C++是一种比C更严格的语言,C++允许的具有潜在危险的隐含物在C++中被排除。 微软文件似乎如警告C2440在C中就同一代码或该代码的一个子集触发错误,即C2440在C++中。

或者,我认为,在我尝试将我的测试方案汇编成C++(/TP)之前,我就认为, 国旗:

>cl /TP cast.c
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.40219.01 for 80x86
Copyright (C) Microsoft Corporation.  All rights reserved.

cast.c
Microsoft (R) Incremental Linker Version 10.00.40219.01
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:cast.exe
cast.obj

如将同一法典编为C++,则无错误或警告。 我相信,我重建了,告诉汇编者,尽可能积极地警告:

>cl /TP /Wall cast.c
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.40219.01 for 80x86
Copyright (C) Microsoft Corporation.  All rights reserved.

cast.c
Microsoft (R) Incremental Linker Version 10.00.40219.01
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:cast.exe
cast.obj

它无声地取得成功。

这些建筑有微软视像C++2010年快版(cl.exe,载于Windows 7 机器,但视像室2003年网的视力XP机器也出现同样的错误:和视觉C++ 2005年快版cl.exe。 因此,在所有版本中似乎都发生了这种情况(尽管我还没有对每一种可能的版本进行测试),而且我机器上安装视频演播室的方式并不成问题。

The same code compiles without a problem in GCC 4.6.1 on an Ubuntu 11.10 system (version string gcc (Ubuntu/Linaro 4.6.1-9ubuntu3) 4.6.1), set to warn as aggressively as possible, as C89, C99, and C++:

$ gcc -ansi -pedantic -Wall -Wextra -o cast cast.c
cast.c: In function ‘main’:
cast.c:6:11: warning: variable ‘q’ set but not used [-Wunused-but-set-variable]

$ gcc -std=c99 -pedantic -Wall -Wextra -o cast cast.c
cast.c: In function ‘main’:
cast.c:6:11: warning: variable ‘q’ set but not used [-Wunused-but-set-variable]

$ g++ -x c++ -ansi -pedantic -Wall -Wextra -o cast cast.c
cast.c: In function ‘int main()’:
cast.c:6:11: warning: variable ‘q’ set but not used [-Wunused-but-set-variable]

确实警告说,在指定之后,从来不会读到<条码>q,但这种警告是有意义的,也是无关紧要的。

除了在海合会发出警告,以及海合会或海卫会无法在C++上发出警告外,我认为,从点到点转换到<代码> 避免*完全不应被视为问题,因为< 编码> 避免* 是非<条码>-const的指点。

在我的实际世界法典(不是例子)中,我可以以<条码>#pragma指令或明确表述的方式,或通过汇编C++(hheh)来保持沉默,或者我只能忽视这一指令。 但我没有做任何事情,至少在我理解为什么发生这种情况之前。 (为什么在C++中发生这种情况!)

一种可能的局部解释是:不同于C++, C允许从<代码>中删除*到任何点对数据类型。 因此,我可以从<条码>const char **到 撤销*,然后从<条码>中默示转换,从到<条码>**,从而可以修改固定数据,使之指向点人,而无需投放。 这将是坏的。 但是,我看不出,这怎么说比C所允许的更弱的类型安全的其他一切情况更糟。

鉴于非<条码>撤销指点类型改为<条码> 撤销*时选择不警告,我可能认为这种警告是合理的:

/* cast.c - Can a const void** be cast implicitly to void* ? */

int main(void)
{
    const void **p = 0;
    void *q;
    q = p;

    return 0;
}
>cl /Wall voidcast.c
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.40219.01 for 80x86
Copyright (C) Microsoft Corporation.  All rights reserved.

voidcast.c
Microsoft (R) Incremental Linker Version 10.00.40219.01
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:voidcast.exe
voidcast.obj

然而,如果是故意的,则:

  1. 微软文件为什么表明在C中产生这种警告的代码在C++中产生错误?

  2. 除了忽视或压制警告外,还有任何其他合理选择,即必须<条码>免费<>/代码>、非<条码>const、非<条码>、条码/代码>(如我的真实情况)数据? 如果在C++发生类似情况,我可以储存一些高级别的STL集装箱而不是一个阵列的变式论点清单中所用的座标。 如果C方案没有进入C++ STL,并且没有其他手段使用高层次的收集,那么这种选择就不是合理的。

  3. 一些方案者在公司/组织政策下将警告视为错误:C4090。 即便有<代码>/W1。 人民以前必须碰到这一点。 这些方案者做了些什么?

最佳回答

很显然,这只是VC++的ug。

如果你宣布<条码>const char **x;,结果就是一个“现成的”点子,而它本身并不是一个“只读”点(因为<条码>const-ness term推崇错误概念,即所指明的特性在总体上是假的......const,其中参照器和点码是参照器或点人的财产,而没有说明点号或参考数据是否一致)。

任何读/正文点均可转换成, 避免*,而VC++在汇编该代码时,既无实际理由发出警告,也无在。 C C++ 模式。

请注意,这不是一个正式的问题,因为标准并没有规定应当或不应发布警告的授权,因此汇编者可以自由发出警告,要求完全有效的守则仍然符合规定。 VC++实际上为有效的C++代码提供了大量的警告。

问题回答

同6502年一样,这似乎在汇编者中是一种ug。 然而,你也问你应该做些什么。

我的回答是,你应该对自由呼吁作出明确表述,然后发表评论,解释为什么需要这种呼吁。 汇编者中确实发生了一些错误,使用了最容易的工作方式,并增加了一个说明,以便如果 b子后来得到解决,就可以对其进行测试。

还要向汇编商供应商报告ug点。

页: 1 这似乎是指在<代码>上添加一个“<>const T *,以删除*,该代码应为C中的警告和C++的错误。





相关问题
Undefined reference

I m getting this linker error. I know a way around it, but it s bugging me because another part of the project s linking fine and it s designed almost identically. First, I have namespace LCD. Then I ...

C++ Equivalent of Tidy

Is there an equivalent to tidy for HTML code for C++? I have searched on the internet, but I find nothing but C++ wrappers for tidy, etc... I think the keyword tidy is what has me hung up. I am ...

Template Classes in C++ ... a required skill set?

I m new to C++ and am wondering how much time I should invest in learning how to implement template classes. Are they widely used in industry, or is this something I should move through quickly?

Print possible strings created from a Number

Given a 10 digit Telephone Number, we have to print all possible strings created from that. The mapping of the numbers is the one as exactly on a phone s keypad. i.e. for 1,0-> No Letter for 2->...

typedef ing STL wstring

Why is it when i do the following i get errors when relating to with wchar_t? namespace Foo { typedef std::wstring String; } Now i declare all my strings as Foo::String through out the program, ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

Window iconification status via Xlib

Is it possible to check with the means of pure X11/Xlib only whether the given window is iconified/minimized, and, if it is, how?

热门标签