我对"int"风格有疑问(unsigned int,long int,long long int).
当我们在32位系统和64位系统中对int和它的味道(比如说long int)之间做一些操作(*,/,+, - )时,"int"会发生隐式类型转换
例如 :-
int x; long long int y = 2000;
x = y; (更高的分配可能会发生更低的一次数据截断)我期待编译器为此发出警告但是我没有收到任何此类警告.这是由于隐式类型转换在这里发生的"x".我正在使用gcc和-Wall选项.是否会改变32位和64位的行为.
谢谢Arpit
为什么我在"BIO_flush(b64);"行中收到此警告消息"警告:未使用值计算" 我怎么能摆脱它呢?
unsigned char *my_base64(unsigned char *input, int length)
{
BIO *bmem, *b64;
BUF_MEM *bptr;
b64 = BIO_new(BIO_f_base64());
bmem = BIO_new(BIO_s_mem());
b64 = BIO_push(b64, bmem);
BIO_write(b64, input, length);
BIO_flush(b64);
BIO_get_mem_ptr(b64, &bptr);
unsigned char *buff = (unsigned char *)malloc(bptr->length+1);
memcpy(buff, bptr->data, bptr->length-1);
buff[bptr->length-1] = 0;
BIO_free_all(b64);
return buff;
}
Run Code Online (Sandbox Code Playgroud) #include <stdio.h>
typedef struct
{
int as;
int bs;
int cs;
}asd_t;
typedef struct
{
asd_t asd[10];
}asd_field_t;
typedef struct
{
int a;
int b;
asd_field_t asd_field[10];
}abc_t;
int main()
{
abc_t abc ={0,1,{0}};
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,我试图初始化结构abc_t.将上面的代码编译为:
gcc -Wall sample.c
Run Code Online (Sandbox Code Playgroud)
给我:
sample.c: In function 'main':
sample.c:26: warning: missing braces around initializer
sample.c:26: warning: (near initialization for 'abc.asd_field[0].asd')
Run Code Online (Sandbox Code Playgroud)
我该如何避免这种警告?
我正在使用#pragma once我的.cpps和.hpps,因此我会收到每个使用它的文件的警告.我没有找到任何选项来禁用这种警告,只有#ifndef MY_FILE_H #define MY_FILE_H /*...*/ #endif.
那么你会建议我#pragma once用ifndefs 替换每个吗?
在标题中:
#define MYFILE_H
// all the header
Run Code Online (Sandbox Code Playgroud)
在其他文件中:
#ifndef MYFILE_H
#include "myfile.hpp"
#endif
// the rest of the file
Run Code Online (Sandbox Code Playgroud)
您怎么看?这样使用它会更好吗?或者有一个选项可以禁用#pragma onceGCC中的警告,我不知道?
我从C Primer Plus中了解到,如果你想保护数组不被函数意外修改,你应该const在函数定义的标题中的指针声明之前添加修饰符.
遵循这个明智的建议,在下面的最小例子中,我试图将一个非常数二维数组array传递给函数Sum2D,其中一个参数是a pointer-to-const-int[2].
#include <stdio.h>
#define ROWS 2
#define COLS 2
int Sum2D(const int ar[][COLS], int rows); //use `const` to protect input array
int main(void)
{
int array[ROWS][COLS]={{1,2},{3,4}}; //the non-constant array
printf( "%d\n", Sum2D(array,ROWS) );
return 0;
}
int Sum2D(const int ar[][COLS], int rows)
{
int total=0;
int i,j;
for( i=0 ; i<rows ; i++ )
{
for( j=0 ; j<COLS ; j++ )
{
total+=ar[i][j];
}
}
return …Run Code Online (Sandbox Code Playgroud) 这是我的编译警告:
src/Debugger.c:219:52: warning: passing argument 2 of ‘Debugger_Command[i].Callback’ from incompatible pointer type
Debugger_Command[i].Callback(argc, argv);
^
src/Debugger.c:219:52: note: expected ‘const char **’ but argument is of type ‘char **’
Run Code Online (Sandbox Code Playgroud)
这是相关的源代码:
/* Definition */
typedef void (*Debugger_Callback_t)(int argc, char const * argv[]);
typedef struct tagDebugger_Command_t {
/* ... */
Debugger_Callback_t Callback; /**< Callback */
} Debugger_Command_t;
Debugger_Command_t const Debugger_Command[] = { /* ... */ }
/* Use of the callback where the warning occurred */
char *argv[DEBUGGER_ARG_COUNT];
Debugger_Command[i].Callback(argc, argv);
Run Code Online (Sandbox Code Playgroud)
将非const变量作为const参数传递有什么问题?据我了解,这是为了确保字符串不会在函数内部被修改.那警告为什么会发生呢?
编译器:Windows/Cygwin上的gcc版本4.9.2(GCC)
我想使用C++ 98和g ++编译器将类标记为已弃用,以便在直接使用此类时或者从某个类派生此类时接收警告.
显然,在使用__attribute__ ((__deprecated__))类时使用工作,但不使用继承.
例如:
#if defined(__GNUC__)
# define DEPRECATED __attribute__ ((__deprecated__))
#else
# define DEPRECATED
#endif
class DEPRECATED Foo
{
public:
explicit Foo(int foo) : m_foo(foo) {}
virtual ~Foo() {}
virtual int get() { return m_foo; }
private:
int m_foo;
};
class Bar : public Foo // This declaration does not produce a compiler
// warning.
{
public:
explicit Bar(int bar) : Foo(bar), m_bar(bar) {}
virtual ~Bar() {}
virtual int get() { return m_bar; }
private: …Run Code Online (Sandbox Code Playgroud) 我注意到以下关于理解严格别名的代码:
uint32_t
swap_words( uint32_t arg )
{
U32* in = (U32*)&arg;
uint16_t lo = in->u16[0];
uint16_t hi = in->u16[1];
in->u16[0] = hi;
in->u16[1] = lo;
return (in->u32);
}
Run Code Online (Sandbox Code Playgroud)
据作者说,
使用GCC 4.0编译时启用-Wstrict-aliasing = 2标志的上述源 将生成警告.这个警告是误报的一个例子.允许这种类型的强制转换,并生成相应的代码(见下文).清楚地记录了-Wstrict-aliasing = 2可能返回误报.
我想知道什么是误报,我应该在别名变量时注意它吗?
以下是上面提到的"适当的代码(见下文)",如果它是相关的:
-fstrict-aliasing -O3 -Wstrict-aliasing -std=c99在GNU C 4.0.0版(Apple Computer,Inc.build 5026)上编译(powerpc-apple-darwin8),
swap_words:
stw r3,24(r1) ; Store arg
lhz r0,24(r1) ; Load hi
lhz r2,26(r1) ; Load lo
sth r0,26(r1) ; Store result[1] = hi …Run Code Online (Sandbox Code Playgroud) 众所周知,自C99以来,调用未声明的函数(最好使用适当的原型)是一个错误。
但是,除此之外,如果我定义的函数在范围内没有原型声明,并且希望包含在调用者使用的同一头文件中,那么我希望编译器警告我。(除非该函数是静态的,否则所有这些都是没有意义的。)
原因应该很明显:如果标头中包含原型声明,并且所有调用者都包含该声明,但是该声明未包含在定义函数的文件中,并且如果该函数的实际定义与外部原型有所不同,则代表调用者完成的所有原型检查都是毫无价值的,实际上适得其反。有一个明显的错误,但是并不能保证完全被抓住。
有通用的编译器可以检查吗?我用-Wall尝试了gcc和clang,但他们没有。(我可以想象,如果Gimpel皮棉仍然存在,它会这样做,但我没有副本。)
理想情况下,我希望它也坚持认为原型存在于单独的头文件中,但是那是一回事,所以我不必坚持。(之所以做出这样的附加规定,是因为一些程序员对假设的警告消息感到厌倦,他们可能会试图通过在.c包含该定义的文件顶部键入一个外部原型来使其静音,这又会破坏目的。 )
我试图理解在C函数声明中使用“ static”关键字作为数组索引的情况。
阅读本文之后,我试图声明一个这样的函数,并有目的地向它传递一个太短的数组:
#include <stdio.h>
#include <stdlib.h>
void print_string10(char string10[static 10]) {
// Should trigger a warning if the argument is NULL or an array of less than 10 elements
printf("%s\n",string10);
}
int main(void) {
char short_string[] = "test";
print_string10(short_string); // should trigger a warning as the string is 5 long
return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)
与clang本文中的一样编译会触发警告,但gcc -Wall -Werror不会,但编译并可以正常运行。
我找不到解释,这是GCC忽略此警告的正常行为吗?