LoginSignup
4

More than 3 years have passed since last update.

posted at

updated at

[C++] ダブルクォーテーションで囲った文字列を関数に渡すことで警告が出るときの理由と対処

環境

  • 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

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
4