warning: the address of ‘func’ will always evaluate as ‘true’
警告:アドレスの無い関数は無い
[-Waddress]
■if(関数名)は必ず成立
warning: the address of ‘func’ will always evaluate as ‘true’
警告:’func’ のアドレスは常に ‘true’ として評価されます。
#include <stdio.h>
int func(void){
puts(__func__);
return 1;
}
int main(void){
if(func){ //func()?
puts(__func__);
}
}
if(func)ではなくて
if(func())の誤りでしょう。
if(func)は
if(関数funcのアドレス) の意味なので常に成立します。
尚、関数ポインタはNULLになる事があるので
if(関数ポインタ)は意味のあるコードです。
参考:
■if(&変数名 != NULL)は必ず成立
#include <stdio.h>
int f1(void) {
int i = 0 ;
if(&i)
return 1;
if(&i != NULL)
return 1;
return 0;
}
アドレスの無い変数はありません。
変数には必ずアドレスがあるので、
変数のアドレスの有無を判定するif文は意味がありません。
■if(&引数名 != NULL)は必ず成立
warning: the comparison will always evaluate as ‘false’ for the address of ‘ptr’ will never be NULL
int f2(int *ptr)
{
if(&ptr == NULL){//ダメ:アドレスの無い引数は無い
return 1;
}
if(ptr == NULL){//修正案
return 1;
}
return 0;
}
引数も変数です。
変数には必ずアドレスがあるので、
3行目if文は意味がありません。おそらく
if(&ptr ==NULL) ではなくて
if( ptr ==NULL) としたかった?
■if(&配列名[0]!=NULL)は必ず成立
warning: the address of ‘ary’ will always evaluate as ‘true’
int f3(void)
{
char ary[1024] = "" ;
if(ary){//ダメ:アドレスの無い配列は無い
return 1;
}
if(ary == NULL){//clangが警告してくれる
return 1;
}
if(&ary[0] == NULL){//残念:警告してくれない
return 1;
}
if(ary[0] == '\0'){//修正案
return 1;
}
return 0;
}
配列も変数です。
変数には必ずアドレスがあるので、
4行目if文は意味がありません。
おそらく
if(ary) ではなくて
if(ary[0] ==’\0′) としたかった?
注意:なぜか、
if(&ary[0] == NULL)と記述すると
コンパイラが警告を出してくれません。
■アドレスの無い変数も実は有る
#include <stdio.h>
int main(void){
register int x = 0;
if(&x == 0){
return 0;
}else{
return 1;
}
}
ここまで読んで頂いて恐縮ですが、
C言語のレジスタ変数にはアドレスが無いので
タイトルは厳密には間違いですね。
上記のコードはレジスタ変数のアドレスを求めているので
gcc,clangではコンパイルエラーになりました。