Tag: visual c ++

是’警告C4127`(条件表达式是不变的)有用吗?

回答这篇文章时,我建议对多行宏使用do {…} while(0) 。 在MSVC上,我发现此代码抛出: warning C4127: conditional expression is constant 为了使代码无警告,我需要选择以下丑陋的替代方案之一: 选项1 #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable:4127) #endif code_using_macro_that_generates_C4217; #ifdef _MSC_VER #pragma warning(pop) #endif 选项2 将我的宏定义为: #define MULTI_LINE_MACRO do { … } while(0,0) 要么 #define MULTI_LINE_MACRO do { … } while((void)0,0) 一些程序员也称为“猫头鹰”,因为(0,0)看起来像猫头鹰。 选项3 定义一个新的宏WHILE_0,它不会生成警告并使用它而不是while(0) 问题 我相信所有选择都或多或少可怕。 为什么MSVC会为看似正确的代码生成此警告,并激励我在代码中添加一些丑陋以保持代码警告免费? 我相信条件中的常量表达式是完全有效的,特别是在基于编译器优化代码的能力的构造中。 此外,我没有得到warning C4127的代码warning C4127 : void […]

为什么VS2010在语法正确时会出现语法错误?

我遇到了VS2010(和VS2008)的问题,给出了一个很好的语法错误列表。 但是,语法确实是正确的。 这是一个小例子; 我在.h文件中有以下代码块 // Prototype Declarations LIST* createList (int (*compare) (void*, void*)); LIST* destroyList (LIST* plist); int addNode (LIST* pList, void* dataInPtr); bool removeNode (LIST* pList, void* keyPtr, void** dataOutPtr); bool searchList (LIST* pList, void* pArgu, void** pDataOut); bool retrieveNode (LIST* pList, void* pArgu, void** dataOutPtr); bool traverse (LIST* pList, int fromWhere, void** dataOutPtr); […]

是否可以使用Visual C ++编译pre-ANSI(K&R-style)C代码?

我们有一些旧的C代码,具有预ANSI(K&R风格)函数声明。 例如: int foo(x, y) double x, y; { /* do some stuff */ } 是否有编译器开关在Visual C ++ 2008中启用对此的支持?

条件表达式中的常量值

在关于无限循环的编码风格问题中 ,有些人提到他们更喜欢for(;;)样式,因为while(true)样式在MSVC上给出关于条件表达式是常量的警告消息。 这让我感到非常惊讶,因为在条件表达式中使用常量值是避免#ifdef地狱的有用方法。 例如,您可以在标题中: #ifdef CONFIG_FOO extern int foo_enabled; #else #define foo_enabled 0 #endif 代码可以简单地使用条件并信任编译器在未定义CONFIG_FOO时删除死代码: if (foo_enabled) { … } 每次使用foo_enabled时都不必测试CONFIG_FOO: #ifdef CONFIG_FOO if (foo_enabled) { … } #endif 这种设计模式一直在Linux内核中使用(例如,include / linux / cpumask.h在禁用SMP时将几个宏定义为1或0,在启用SMP时定义为函数调用)。 MSVC警告的原因是什么? 另外,有没有更好的方法来避免#ifdef hell而不必禁用该警告? 或者这是一个过于宽泛的警告,一般不应该启用?

是否有一种类型安全的方法来获取C中数组的元素数?

在C中获取数组元素的通常方法是这样的: #define COUNTOF(arr) (sizeof(arr) / sizeof(arr[0])) 这导致了一个整数常量表达式,这也是一个非常好的加号。 问题是它不是类型安全的: int* i; COUNTOF(i); /* compiles 🙁 */ int* i; COUNTOF(i); /* compiles 🙁 */ int* i; COUNTOF(i); /* compiles 🙁 */ 。在实践中,这应该很少出现,但为了正确起见,这将是很好的使这种类型安全。 在C ++ 03中,这很容易(在C ++ 11中,它更容易,留给读者练习): template char (&countof_detail(T (&)[N]))[N]; // not defined #define COUNTOF(arr) (sizeof(countof_detail(arr))) 这使用模板推导来获得N ,即数组的大小,然后将其编码为类型的大小。 但在C语言中,我们没有获得该语言function。 这是我做的小框架: // if `condition` evaluates to 0, […]

Visual C ++ / Studio:应用程序配置不正确?

我的C(++)程序,使用Visual C(++)/ Visual Studio编写和编译,在我自己的机器上运行良好,但拒绝在另一台机器上运行。 我得到的错误消息是“此应用程序无法启动,因为应用程序配置不正确。重新安装应用程序可能会解决此问题。”

C89,混合变量声明和代码

我很好奇,当你尝试混合变量声明和代码时,为什么C89编译器会转储给你,例如: rutski@imac:~$ cat test.c #include int main(void) { printf(“Hello World!\n”); int x = 7; printf(“%d!\n”, x); return 0; } rutski@imac:~$ gcc -std=c89 -pedantic test.c test.c: In function ‘main’: test.c:7: warning: ISO C90 forbids mixed declarations and code rutski@imac:~$ 是的,你可以避免这种事情,远离-pedantic。 但是,您的代码不再符合标准。 正如任何能够回答这篇文章的人可能已经知道的那样,这不仅仅是一个理论上的问题。 像Microsoft的C编译器这样的平台在任何和所有情况下都可以在标准中快速执行。 鉴于古老的C是多么的,我认为这个特征是由于一些历史问题可以追溯到70年代的非凡硬件限制,但我不知道细节。 或者我完全错了吗?

如何将C-struct指定的初始化程序重写为C89(resp MSVC C编译器)

伙计们,我有这个问题: 通常在C99 GCC(cygwin / MinGW / linux)中,C struct中的初始化器有点符号语法。 像这样: //HELP ME HOW TO REWRITE THIS (in most compact way) to MSVC static struct my_member_t my_global_three[] = { {.type = NULL, .name = “one”}, {.type = NULL, .name = “two”}, {.type = NULL, .name = “three”}, }; 将my_memeber_t定义在头文件中: struct my_member_t { struct complex_type * type; char […]

使用scanf_s读取字符

我只是乱搞C并遇到了这个小问题。 正如你从我的输出中看到的那样,我得到了’╠’这个角色。 #include “stdio.h” void main() { char c; printf(“Do you want to be X’s or O’s?\n”); scanf_s(“%c”, &c); printf(“You chose %c\n”, c); } 见程序输出

为什么Visual C ++警告在C中隐式转换从const void **到void *,而不是在C ++中?

摘要 当C程序尝试将指向const数据(如const void **或const char ** )的指针转换为void *时,Microsoft Visual Studio中的C / C ++编译器会发出警告C4090 (即使这样的类型实际上不是指向const的指针。 更奇怪的是,同一个编译器默默接受编译为C ++的相同代码。 这种不一致的原因是什么,为什么Visual Studio(与其他编译器不同)有一个问题,即将指向const的指针隐式转换为void * ? 细节 我有一个C程序,其中在变量参数列表中传递的C字符串被读入一个数组(通过调用va_arg的循环)。 由于C字符串的类型为const char * ,因此跟踪它们的数组的类型为const char ** 。 这个带有const内容的字符串指针数组本身是动态分配的(使用calloc ),我在函数返回之前free它(在处理C字符串之后)。 当我使用cl.exe (在Microsoft Visual C ++中)编译此代码时,即使警告级别较低, free调用也会触发警告C4090 。 由于free取一个void * ,这告诉我编译器不喜欢我将const char **转换为void * 。 我创建了一个简单的例子来证实这一点,我尝试将const void **转换为void * : /* cast.c – Can a […]