2012-05-05 7 views
2

これは私がC言語でマクロを使用している初めてのことです。通常はマクロに関数の中に入れたいコードの大きな部分を置き換えようとしています。これは非常に頻繁に使用される割り込みの一部なので、可能な限り最適化する必要があります。ドキュメントを読んだ後、私はコンパイラが関数のインライン展開をサポートしていないことを知り、関数呼び出しのオーバーヘッドを避けたい。このCマクロが構文エラーを引き起こすのはなぜですか?

コード自体はデータをシリアル・イン・パラレル・アウト・シフト・レジスタに送信します。私が見る限り、必要なコードを書き込むための方法はありません。

私はC18コンパイラバージョン3.41とMPLAB X IDEを使用しています。

だからここで私は、関数の形で使用しているコードです:

void first_one(void) 
{ 
    //3 invisible zeroes 
      LATBbits.LATB1=0; //data set to zero 

      LATBbits.LATB0=1;//first clock 
      LATBbits.LATB0=0; 

      LATBbits.LATB0=1;//second clock 
      LATBbits.LATB0=0; 

      LATBbits.LATB0=1;//third clock 
      LATBbits.LATB0=0; 
      //end of invisible zeroes 

      //two visible zeroes  
      LATBbits.LATB0=1;//first clock 
      LATBbits.LATB0=0; 

      LATBbits.LATB0=1;//second clock 
      LATBbits.LATB0=0; 
      //end of two visible zeroes 

      LATBbits.LATB1=1;//Data is now one 

      LATBbits.LATB0=1; 
      LATBbits.LATB0=0; 
      //one 

      LATBbits.LATB1=0;//Data is now zero 

      LATBbits.LATB0=1;//first clock 
      LATBbits.LATB0=0; 

      LATBbits.LATB0=1;//second clock 
      LATBbits.LATB0=0; 

      //after this, everything should be in place 
      LATBbits.LATB0=1; 
      LATBbits.LATB0=0; 
} 

私は、この関数をマクロになってきました:

#define first_one() { \ 
\ 
      LATBbits.LATB1=0;\    
           \ 
      LATBbits.LATB0=1;\ 
      LATBbits.LATB0=0;\ 
           \ 
      LATBbits.LATB0=1;\ 
      LATBbits.LATB0=0;\ 
          \ 
      LATBbits.LATB0=1;\ 
      LATBbits.LATB0=0;\ 
      \         
      LATBbits.LATB0=1;\ 
      LATBbits.LATB0=0;\ 
\ 
      LATBbits.LATB0=1;\ 
      LATBbits.LATB0=0;\ 
      \ 
      LATBbits.LATB1=1;\ 
\ 
      LATBbits.LATB0=1;\ 
      LATBbits.LATB0=0;\  
\ 
      LATBbits.LATB1=0;\ 
      ^^^ The syntax error is here! 
\ 
      LATBbits.LATB0=1;\ 
      LATBbits.LATB0=0;\ 
\ 
      LATBbits.LATB0=1;\ 
      LATBbits.LATB0=0;\ 
\ 
      LATBbits.LATB0=1;\ 
      LATBbits.LATB0=0;\ 
\ 
        } 

だから私は間違って何をやっていますか?

更新:コメントを削除しました。別の場所で構文エラーが発生しています。

+0

なぜあなたはマクロに関数を回す必要があると思いますか?関数呼び出しのオーバーヘッドが重要な場合は、インライン関数にしてください。 –

+0

@ Paul R私が質問したように、コンパイラは関数のインライン展開をサポートしていません。 – AndrejaKo

+1

...しかし、Paulが言ったように、関数呼び出しのオーバーヘッドはここで重要です。これは結局は1行の関数ではありません。私に[早期最適化](http://c2.com/cgi/wiki?PrematureOptimization)のように見えます。 – Clifford

答えて

8

\トークンの後に空白がないことを確認します。コンパイラによってはコンパイルエラーが発生するものがあります。

+0

空白がないかどうか確認し、エラーがないことを確認してください。 – AndrejaKo

+0

実際これが問題であることが判明しました。 IDEを何度か再起動してプログラムが正常にコンパイルされたのを見て、 '\'の後ろにスペースを追加しようとしました。 – AndrejaKo

+2

ヒント:エディタで、マクロ内のすべてのテキストを選択/強調表示します。末尾のスペースは、問題のある行の最後に色付きのブロックとして表示されます。投稿された質問のテキストを使ってそのことを行うこともできますし、問題がどこにあるかを確認することもできます。 – Clifford

3

コメントが削除される前に回線がスプライスされているため、\//3 invisible zeroes \は回線を継続しません。

あなたがラインを続けて\前にコメントコメントを削除するか、Cスタイルのコメント(/* 3 invisible zeroes */)を使用して配置するのいずれかが必要です。

+0

主な問題のように見えるのはコメントではありません。私はそれらを削除し、まだ構文エラーを取得しています。 – AndrejaKo

+0

構文エラーとは何ですか?前処理されたソースを見て、何が間違っているかを見つけてください(gccとVisual C++で '-E'を使ってコンパイルしてください)。 –

+0

構文エラーは 'Error:syntax error'ですのであまり役に立ちません。 Visual StudioとGCCは私が今すぐコードを書いているプラ​​ットフォームをサポートしていません。 – AndrejaKo

1

問題は、コメントとプリプロセッサがそれらを処理する方法にあります。コメントを削除しても問題ありません。 代替使用/ *コメント*/

1

三の提案:

まず、各\後に任意の末尾にスペースがないことを確認してください。

次に、マクロ名から ()を削除します(引数が不要な場合)。 編集以下のコメントを入力してください。

最後に、マクロの内容をdo {...} while(0)(後続のセミコロンなし)で囲みます。このようにして、コードにfirst_one();と書くと、閉じ括弧の後に偽のセミコロンが付きません。要するに

#define do_first   \ 
    do {     \ 
    LATBbits.LATB0 = 1; \ 
    ...     \ 
    } while(0) 

編集ランディンが、これは昔ながらおよび不要であることを指摘しています。私はいつも、マクロがフォーム{...};の形式に展開されていれば、診断を避ける必要があると信じていました。私はまだ文体の選択としてそれを好む。

+4

引数をとらなくても、関数のように振る舞うはずのマクロから()を省略することは決してありません。これはコードを裸のシンボルではなく読みやすくする(これは文のような関数です)。 –

+0

私はこれに同意します。将来的に標準のCコンパイラを入手した場合は、マクロをCのように見せ、インライン関数と互換性を持たせるためには常にuse()を使用します。また、do-whileのアドバイスは昔ながらのものです。すべての現代のC言語標準では、各ステートメントの後に{}が適用されており、バグの数を大幅に減らしています。あなたがコーディング規律を持っているなら、do-whileは不要です。 – Lundin

+0

@ Lundin:私は気が狂っています。私は*誓い* {...};が胸焼けを引き起こしていたかもしれないが、gccは-pendaticを使ってもうまく嚥下する。そして、私は '()'を保つ理由を受け入れます。私は象徴的な定数を超えて何かのためにマクロを使うのをやめようとする傾向があります。 –

関連する問題