環境
- BeagleBone Black Rev.C
- BeagleBoard.org Debian Image 2016-11-06(/etc/dogtag)
- Debian8.6(2016.11.6)
- コンパイラ
- gcc (Debian 4.9.2-10+deb8u2) 4.9.2
概要
fopen() にファイルポインタをオープンできたかを確認する機能を追加した関数,Myfopen() を呼び出した際に警告が出た.
sample.c
#include <stdio.h>
#include <stdlib.h>
FILE *Myfopen(char Path[], char Mode[])
{
FILE *fp = fopen(Path, Mode);
if(fp == NULL)
{
printf("OpenError.[%s](%d)\n", Path, Mode);
exit(1);
}
return fp;
}
int main(void)
{
FILE *fp = Myfopen("sample.txt", "r");
return 0;
}
これをコンパイルすると,以下のような警告が出る.
debian@beaglebone:~/share/program/src$ g++ sample.cpp
sample.cpp: In function 'int main()':
sample.cpp:17:41: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
FILE *fp = Myfopen("sample.txt", "r");
^
sample.cpp:17:41: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
この警告が出る理由と対処について説明する.
警告が出る理由
C++では文字列リテラル(ダブルクォーテーションで囲われた文字列)は、const char 配列として扱われる.したがって~~関数(Myfopen)に渡される文字列は const char [] であるのに関わらず,関数の仮引数の型は char []~~
関数(Myfopen)に渡される文字列は const char であるのに関わらず,関数の仮引数の型は char [](char)**である.これが理由である.
(2018/12/22 訂正)
対処
関数へ渡す引数が const char* であるため,関数の仮引数の型も const char [](const char*) にすればよい.
sample.c
/* 変更後 */
FILE *Myfopen(const char Path[], const char Mode[])
{
FILE *fp = fopen(Path, Mode);
if(fp == NULL)
{
printf("OpenError.[%s](%d)\n", Path, Mode);
exit(1);
}
return fp;
}
これによって警告を出すことなくコンパイルすることができる.
参考
C++において,文字列リテラルから 'char*型' への変換が非推奨? エラーメッセージ
https://teratail.com/questions/9652