質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.46%

  • C

    3825questions

    C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

  • コンパイルエラー

    31questions

    コンパイルのフェーズで生成されるエラーです。よく無効なシンタックスやタイプが含まれているとき発生します。

C言語 initilizer element is not constant

解決済

回答 3

投稿

  • 評価
  • クリップ 1
  • VIEW 1,209

simasimaa

score 33

gcc を使っていてinitilizer element is not constantというエラーが出ました。

#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <string.h>

#define pi 3.141592653589793
#define c 2.998e8
#define e0 8.854e-12
#define u0 1.256637061e-6
#define media 10

#define dx 0.02
#define dy 0.02
#define dz 0.02

#define nx 60
#define ny 60
#define nz 60

#define nt 400

#define frequency 200.0e6

#define permittivity_0 8.854e-12
#define permittivity_1 1.239e-10
#define permittivity_2 7.083e-11
#define permittivity_3 3.0e-11

#define permeability_0 1.256637061e-6
#define permeability_1 1.256637061e-6
#define permeability_2 1.256637061e-6
#define permeability_3 1.256637061e-6

#define conductivity_0 0.01
#define conductivity_1 10.0
#define conductivity_2 0.01
#define conductivity_3 0.1





double dxt=c/dx;
double dyt=c/dy;
double dzt=c/dz;

double dt=1.0/sqrt(dxt*dxt+dyt*dyt+dzt*dzt);
double rh1=dt/u0;
double rh2=dt/e0;

double vvx=c*dt-dx;
double wwx=c*dt+dx;
double ux1=vvx/wwx;
double ux2=2.*dx/wwx;
double ux3=dx*c*c*dt*dt/2./dy/dy/wwx;
double ux4=dx*c*c*dt*dt/2./dz/dz/wwx;

double vvy=c*dt-dy;
double wwy=c*dt+dy;
double uy1=vvy/wwy;
double uy2=2.*dy/wwy;
double uy3=dy*c*c*dt*dt/2./dz/dz/wwy;
double uy4=dy*c*c*dt*dt/2./dx/dx/wwy;

double vvz=c*dt-dz;
double wwz=c*dt+dz;
double uz1=vvz/wwz;
double uz2=2.*dz/wwz;
double uz3=dz*c*c*dt*dt/2./dx/dx/wwz;
double uz4=dz*c*c*dt*dt/2./dy/dy/wwz;


double exi[nx][ny][nz];
double eyi[nx][ny][nz];
double ezi[nx][ny][nz];

double hxi[nx][ny][nz];
double hyi[nx][ny][nz];
double hzi[nx][ny][nz];

double exy1[nx][ny][nz];
double exz1[nx][ny][nz];
double eyx1[nx][ny][nz];
double eyz1[nx][ny][nz];
double ezy1[nx][ny][nz];
double ezx1[nx][ny][nz];

double exy2[nx][ny][nz];
double exz2[nx][ny][nz];
double eyx2[nx][ny][nz];
double eyz2[nx][ny][nz];
double ezy2[nx][ny][nz];
double ezx2[nx][ny][nz];

double cex_0,cey_0,cez_0,chx_0,chy_0,chz_0;
double cexly_0,cezly_0,cezlx_0,ceylx_0,ceylz_0,cexlz_0;
double chxly_0,chxlz_0,chylz_0,chylx_0,chzlx_0,chzly_0;
double cex[media],cey[media],cez[media];
double ceylz[media],chylz[media],cexlz[media],chxlz[media];
double cexly[media],cezly[media],cezlx[media],ceylx[media];
double chxly[media],chzly[media],chzlx[media],chylx[media];

double permittivity[media];
double permeability[media];
double conductivity[media];

int idex[nx][ny][nz],idey[nx][ny][nz],idez[nx][ny][nz];
int idhx[nx][ny][nz],idhy[nx][ny][nz],idhz[nx][ny][nz];

void input();
void modeling();
void shoki(int n);
void ecur_source(double time,int i_position,int j_position,int k_position);
void electric_field();
void magnetic_field();
void output_conter(FILE *fp);
void mur_1st();

int main()
{

コード


これの47~70行にかけてずらっとinitializer element is not constant
で出ています。clangというコンパイラなら出ないと検索してわかったので試してみましたが、
C:\Program Files (x86)\Windows Kits\10\Include\10.0.10240.0\ucrt\corecrt.h:10:10
: fatal error:
'vcruntime.h' file not found

include <vcruntime.h>

1 error generated.
というエラーが出ます。できればgcc のコンパイラを使って解決したいですがどうすればいいですか?

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

checkベストアンサー

0

こんにちは。

clangでも同じエラーになりました
dxtなどがコンパイル時定数として認識されていないからです。

安易な対策は下記と思います。

#define dxt (c/dx)

ところで、c++ならそのままでもコンパイルできました

組込系でないのであれば、この機会にC++にグレードアップするのも選択肢かもしれません。C++の全ての機能を使おうとするとたいへんですが、便利と思った機能だけつまみ食いするのも有りと思いますよ。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/09/06 12:26

    些細なことですが、cもdxも定数なのでdxtの初期値は定数ですよ。(混乱する人がいるかもしれないのでコメントしました)

    キャンセル

  • 2017/09/06 15:48

    エラーメッセージが「constant(定数)でない」と言ってますから、コンパイラは定数とは解釈していないと思いますよ。

    とはいえ、ちょっと気になったので確認したのですが「安易な対策」でもまだ不足でした。
    sqrt()が入っているから、これがコンパイル時定数になるのを阻んでます。dxt等を#defineとし、かつ、sqrtを外して、やっとエラーになりませんでした。
    つまり、C言語は初期化子にはコンパイル時定数しか許さないということのようです。

    C++は初期化時に関数を呼び出すことができますから、エラーにならないのだと思います。

    キャンセル

  • 2017/09/06 16:42

    47行目は、その行ではありませんよ
    47行目は、double dt=1.0/sqrt(dxt*dxt+dyt*dyt+dzt*dzt);
    他の回答者もそうよんでますよ

    キャンセル

  • 2017/09/06 17:56

    エラーがでているのは47行目のdouble dt=1.0/sqrt(dxt*dxt+dyt*dyt+dzt*dzt);ですね。
    sqrt()に言及していることでわかると思いますが、私もそう読んでます。

    このエラーの原因は2つあります。sqrt()を呼んでいることとdxt, dyt, dztを使っていることです。暫定的にsqrtを外し、dxt, dyt, dztの定義を#defineへ変更するとコンパイル・エラーはなくなります。(もちろん、元のソースと動作が異なるので、正しい修正ではないです。コンパイル・エラー原因をつかむための暫定修正です。)
    double dxt=c/dx;にて定義したdxt等、および、sqrt()呼び出しの結果をコンパイラがコンパイル時定数として認識しないことが原因です。

    #define dxt (c/dx)によりdxtは(c/dx)へ置き換えられ、更に(2.998e8/0.02)へ置き換えられます。
    これは定数同士の演算なのでコンパイラがコンパイル時に計算できます。更にdyt, dztを#defineへ変更し、sqrt()を外すと1.0/(dxt*dxt+dyt*dyt+dzt*dzt)は全て定数演算となり、コンパイル時に計算できますから「コンパイル時定数」となるため、初期化に用いることができるようになります。

    ところで、double dxt=c/dx; として定義したdxtは定数ではありません。値を変更できますから変数です。
    つまり、dxtの初期値が定数だったとしてもdxt自身は変数ですから、コンパイル時定数としてコンパイラが認識しないため、他の変数の初期化子として使えないということなのです。

    dxtは#defineに置き換えることでどうにかなりますが、sqrt()をコンパイル時に計算する仕組みはC言語にはないため、こちらはどうしようもありません。
    ですので、otnさんの回答のように初期化子での初期化を諦めるのが妥当と思います。
    もし、C++へ移行可能なら、C++なら初期化子で関数を呼び出せるので楽できます。

    キャンセル

  • 2017/09/06 20:07 編集

    double dxt=c/dx;の行をdefineで置き換えてるので、そので行でエラーが発生していると勘違いしての発言だと思ったしだいです。

    キャンセル

  • 2017/09/07 16:02

    ありがとうございます!

    キャンセル

0

数が多いので面倒ですが、宣言と代入を分離しましょう。

double dt=1.0/sqrt(dxt*dxt+dyt*dyt+dzt*dzt);


double dt;
~~~
int main()
{
dt=1.0/sqrt(dxt*dxt+dyt*dyt+dzt*dzt);
~~~~

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/09/07 16:01

    ありがとうございます!

    キャンセル

0

C11仕様書最終ドラフトN1570で確認しました。

「6.7.9 Initialization」の4で、静的記憶期間(static storage duration)またはスレッド記憶期間(thread storage duration)であるオブジェクト(object、変数に入るメモリ上のデータのこと、オブジェクト指向のオブジェクトのことではない)の初期化子(initializer、初期化付き変数宣言での=の右辺の部分)は定数式(constant expression)または文字列リテラル(string literal)でなければならないとしています。

グローバル変数は静的記憶期間のオブジェクトです(参照:「6.2.4 Storage durations of objects」の3)ので、コードの各変数の初期化子も定数式か文字列リテラルである必要があります。文字列リテラルは"abc"といった文字列を表すリテラレルのことですので、説明を省きます。では、定数式は何かというと「6.6 Constant expressions」で定義されています。

「6.6 Constant expressions」によると、関数呼び出し(function-call)は含める事はできない(3)としています。また、定数式はそれ自体またはその評価結果が算術定数式かヌルポインタ定数かアドレス定数かアドレス定数を算術定数式で増減したものでなければならない(7)としています。算術定数式は整数定数、浮動小数点定数、列挙定数、文字定数、sizeof_Alignofのみです(8)。ただし、他の形の定数式を実装依存で受け入れても良い(10)としています。つまり、実装依存の部分を除けば、初期化子は定数として評価されるものでならなければなりません。

※ わかっていると思いますが、C言語での「定数(constant)」はconst修飾子が付いた変数のことではありません。他の言語ではリテラルなどと言われる1'a'などのみを定数と言います。

さてコードを見るとdouble dt=1.0/sqrt(dxt*dxt+dyt*dyt+dzt*dzt);の部分はsqrt()の関数呼び出しを行っていますので、Cの仕様としては定数式になっていません。まずはこの部分でコンパイルエラーが置きます。次にdouble rh1=dt/u0;ですが、u0は定数ですがdtは定数ではありません。そのため、dt/u0は定数式ではありませんので、同じくコンパイルエラーになります。

おっとここでconst double dt=1.0;とするとClangではdouble rh1=dt/u0;の部分はエラーになりません。どうやら、constで宣言したグローバル変数については、実装依存のその他の形式としてClangでは許されているようです。GCCでは許されていませんので、同じくエラーになります。

ということで、実装依存が無いCの標準に即した書き方をするのであれば、全てを定数または定数のみで演算している定数式で初期化子を書くか、コンパイル時評価を諦めて、mainの初めに初期化していくしかないでしょう。

なお、C++の初期化子は上記とは異なりますのでご注意ください。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/09/07 16:01

    ありがとうございます!

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.46%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • C

    3825questions

    C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

  • コンパイルエラー

    31questions

    コンパイルのフェーズで生成されるエラーです。よく無効なシンタックスやタイプが含まれているとき発生します。