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

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

新規登録して質問してみよう
ただいま回答率
85.48%
C

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

コンパイルエラー

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

Q&A

解決済

3回答

15635閲覧

C言語 initilizer element is not constant

simasimaa

総合スコア41

C

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

コンパイルエラー

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

0グッド

1クリップ

投稿2017/09/05 06:10

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

c言語

1#include <stdlib.h> 2#include <stdio.h> 3#include <math.h> 4#include <string.h> 5 6#define pi 3.141592653589793 7#define c 2.998e8 8#define e0 8.854e-12 9#define u0 1.256637061e-6 10#define media 10 11 12#define dx 0.02 13#define dy 0.02 14#define dz 0.02 15 16#define nx 60 17#define ny 60 18#define nz 60 19 20#define nt 400 21 22#define frequency 200.0e6 23 24#define permittivity_0 8.854e-12 25#define permittivity_1 1.239e-10 26#define permittivity_2 7.083e-11 27#define permittivity_3 3.0e-11 28 29#define permeability_0 1.256637061e-6 30#define permeability_1 1.256637061e-6 31#define permeability_2 1.256637061e-6 32#define permeability_3 1.256637061e-6 33 34#define conductivity_0 0.01 35#define conductivity_1 10.0 36#define conductivity_2 0.01 37#define conductivity_3 0.1 38 39 40 41 42 43double dxt=c/dx; 44double dyt=c/dy; 45double dzt=c/dz; 46 47double dt=1.0/sqrt(dxt*dxt+dyt*dyt+dzt*dzt); 48double rh1=dt/u0; 49double rh2=dt/e0; 50 51double vvx=c*dt-dx; 52double wwx=c*dt+dx; 53double ux1=vvx/wwx; 54double ux2=2.*dx/wwx; 55double ux3=dx*c*c*dt*dt/2./dy/dy/wwx; 56double ux4=dx*c*c*dt*dt/2./dz/dz/wwx; 57 58double vvy=c*dt-dy; 59double wwy=c*dt+dy; 60double uy1=vvy/wwy; 61double uy2=2.*dy/wwy; 62double uy3=dy*c*c*dt*dt/2./dz/dz/wwy; 63double uy4=dy*c*c*dt*dt/2./dx/dx/wwy; 64 65double vvz=c*dt-dz; 66double wwz=c*dt+dz; 67double uz1=vvz/wwz; 68double uz2=2.*dz/wwz; 69double uz3=dz*c*c*dt*dt/2./dx/dx/wwz; 70double uz4=dz*c*c*dt*dt/2./dy/dy/wwz; 71 72 73double exi[nx][ny][nz]; 74double eyi[nx][ny][nz]; 75double ezi[nx][ny][nz]; 76 77double hxi[nx][ny][nz]; 78double hyi[nx][ny][nz]; 79double hzi[nx][ny][nz]; 80 81double exy1[nx][ny][nz]; 82double exz1[nx][ny][nz]; 83double eyx1[nx][ny][nz]; 84double eyz1[nx][ny][nz]; 85double ezy1[nx][ny][nz]; 86double ezx1[nx][ny][nz]; 87 88double exy2[nx][ny][nz]; 89double exz2[nx][ny][nz]; 90double eyx2[nx][ny][nz]; 91double eyz2[nx][ny][nz]; 92double ezy2[nx][ny][nz]; 93double ezx2[nx][ny][nz]; 94 95double cex_0,cey_0,cez_0,chx_0,chy_0,chz_0; 96double cexly_0,cezly_0,cezlx_0,ceylx_0,ceylz_0,cexlz_0; 97double chxly_0,chxlz_0,chylz_0,chylx_0,chzlx_0,chzly_0; 98double cex[media],cey[media],cez[media]; 99double ceylz[media],chylz[media],cexlz[media],chxlz[media]; 100double cexly[media],cezly[media],cezlx[media],ceylx[media]; 101double chxly[media],chzly[media],chzlx[media],chylx[media]; 102 103double permittivity[media]; 104double permeability[media]; 105double conductivity[media]; 106 107int idex[nx][ny][nz],idey[nx][ny][nz],idez[nx][ny][nz]; 108int idhx[nx][ny][nz],idhy[nx][ny][nz],idhz[nx][ny][nz]; 109 110void input(); 111void modeling(); 112void shoki(int n); 113void ecur_source(double time,int i_position,int j_position,int k_position); 114void electric_field(); 115void magnetic_field(); 116void output_conter(FILE *fp); 117void mur_1st(); 118 119int main() 120{ 121 122コード

これの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 のコンパイラを使って解決したいですがどうすればいいですか?

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

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/06 12:29

raccy

総合スコア21735

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

simasimaa

2017/09/07 07:01

ありがとうございます!
guest

0

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

C

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

C

1double dt; 2~~~ 3int main() 4{ 5dt=1.0/sqrt(dxt*dxt+dyt*dyt+dzt*dzt); 6~~~~

投稿2017/09/05 06:36

otn

総合スコア84499

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

simasimaa

2017/09/07 07:01

ありがとうございます!
guest

0

ベストアンサー

こんにちは。

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

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

C

1#define dxt (c/dx)

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

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

投稿2017/09/05 06:34

Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tmp

2017/09/06 03:26

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

2017/09/06 06:48

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

2017/09/06 07:42

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

2017/09/06 08: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++なら初期化子で関数を呼び出せるので楽できます。
tmp

2017/09/06 11:07 編集

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

2017/09/07 07:02

ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問