マイコン入門spacer ad
トップページに戻る(マイコン徹底入門:STM32で始めるARM/Cortex-M3組み込み開発)
「マイコン徹底入門」とは? |  「マイコン徹底入門」を読む |  ダウンロード |  掲示板 |  筆者の自己紹介


Previous: 11.1.2. 変数の属性

Up: 11.1. ファームウェアライブラリでのコード規約

Next: 11.2. ファームウェアライブラリでの定義値


マイコン徹底入門:導入編:オープンソースでCortex-M3/STM32の開発環境を無償構築: 11. ファームウェアライブラリの利用上の規約: 11.1. ファームウェアライブラリでのコード規約:

11.1.3. 変数の宣言の仕方のまとめ

 C99IOタイプ識別子の両方をまとめると、変数は以下のように宣言することになります。

11?3 C99IOタイプ識別子を使用した変数宣言

通常の宣言

CMSISでの宣言

 

signed

long

 

int32_t

 

signed

short

 

int16_t

 

signed

char

 

int8_t

 

signed

long

const

const int32_t

 

signed

short

const

const int16_t

 

signed

char

const

const int8_t

volatile

signed

long

 

__O int32_t

__IO int32_t

volatile

signed

short

 

__O int16_t

__IO int16_t

volatile

signed

char

 

__O int8_t

__IO int8_t

volatile

signed

long

const

__I int32_t

volatile

signed

short

const

__I int16_t

volatile

signed

char

const

__I int8_t

 

unsigned

long

 

uint32_t

 

unsigned

short

 

uint16_t

 

unsigned

char

 

uint8_t

 

unsigned

long

const

const uint32_t

 

unsigned

short

const

const uint16_t

 

unsigned

char

const

const uint8_t

volatile

unsigned

long

 

__O uint32_t

__IO uint32_t

volatile

unsigned

short

 

__O uint16_t

__IO uint16_t

volatile

unsigned

char

 

__O uint8_t

__IO uint8_t

volatile

unsigned

long

const

__I uint32_t

volatile

unsigned

short

const

__I uint16_t

volatile

unsigned

char

const

__I uint8_t

コラム11?2関数の文字列引数の型とint8_t

 本文中で指摘したstdint.hの後のint8_tの定義の変更を行わない場合、プロトタイプ型が

void USART2_Send_String(int8_t String[]);

である関数を、

USART2_Send_String("Messeage");

と、文字列リテラルを引数にして呼び出すと、コンパイル時に、

pointer targets in passing argument 1 of ‘USART2_Send_String’ differ in signedness

という警告が発生します。変数の符号が違うという警告ですが。これはgccchar型を、signed char(int8_t)unsigned char(uint8_t)とは別の符号であると見なすためです。つまりコンパイラは”Messeage”を文字列リテラルであるからchar型とみなす一方で、引数を受ける関数の型がint8_t(signed char)とは符号が違うので、警告しているわけです。char型をことさらにsigned char型とは違う型であるとみなす必然性もないでしょうし、警告の文面も不親切といえますが、コンパイラの仕様なので仕方がありません。

 これに対する解決策としては、gccの文字列リテラルの型の扱いを変更できることが一番望ましいのですが現状では不可能のようです。そこで以下のような方法が考えられますが、それぞれメリットデメリットがあります。

コンパイラの設定を変更して警告をさせないようにする

この部分はプログラムとしては問題ないコードなのでよいが、本当に符号を間違えたときに気づきにくくなる

stdint.h内のint8_tの定義をcharに変更する/-fsigned-charオプションをつけてコンパイルし単なるchar型をsigned char型として扱わせる

C99への準拠性が低くなる。ツールチェインの更新の度に再コンパイルが必要。

文字列リテラルを一旦int8_t型の配列に格納してから関数に渡す

プログラムが冗長になる。char型の引数を持つ標準ライブラリ関数に対応できない。

文字列リテラルを(int8_t *)でキャストする

プログラムが若干冗長になる。char型の引数を持つ標準ライブラリ関数に対応できない。

 以上のように筆者が思いついた方法はどれも一長一短があります。この中で、一番対応が楽で、プログラムの汎用性が失われないと思われる方法がstdint.hの定義を修正する方法でした。

 この問題について他に有効な解決策がありましたら、是非筆者までお知らせください。


Previous: 11.1.2. 変数の属性

Up: 11.1. ファームウェアライブラリでのコード規約

Next: 11.2. ファームウェアライブラリでの定義値


このページはITと知的財産の法律情報「法務ネット」の管理人が制作・運営しています。