討論區快速選單
知識庫快速選單
掌握Salesforce雲端管理秘訣 討論區最近新進100則主題 政府補助!學嵌入式+物聯網
[ 回上頁 ] [ 討論區發言規則 ]
不能從non constant自動轉成constant?
更改我的閱讀文章字型大小
作者 : sunyear() VC++卓越專家C++頂尖高手貼文超過2000則
[ 貼文 2421 | 人氣 1485 | 評價 6060 | 評價/貼文 2.5 | 送出評價 5 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2013/1/9 下午 07:09:04
void fun1(const int *p){}
void fun2(const int **pp){}

int _tmain()
{
int *p= new int [10];
fun1(p);//non constant convert to constant OK
int **pp= new int *[10];
fun2(pp);//error C2664: 'fun2' : cannot convert parameter 1 from 'int **' to 'const int **'
return 0;
}
//VC2010
//為什麼fun2不能從non constant自動轉成constant?
作者 : sunyear(coco) VC++卓越專家C++頂尖高手貼文超過2000則
[ 貼文 2421 | 人氣 1485 | 評價 6060 | 評價/貼文 2.5 | 送出評價 5 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2013/1/9 下午 07:33:26
找到了:
http://support.microsoft.com/kb/122443/en-us
文章是2005的,到現在都還沒解決?真是有夠X!
作者 : sunyear(coco) VC++卓越專家C++頂尖高手貼文超過2000則
[ 貼文 2421 | 人氣 1485 | 評價 6060 | 評價/貼文 2.5 | 送出評價 5 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2013/1/9 下午 08:14:05
>http://support.microsoft.com/kb/122443/en-us
抱歉,這個不是我的例子。

這個才是:
http://support.microsoft.com/kb/87020/en-us
但有點看不給它懂???
int I = 8;
int * pI = &I;
const int ** ppcI = &pI; // this should not be allowed because later attempts
     // to perform the assignment "*pI = 0;" would
     // modify the value "**ppcI" that was declared as
     // being constant.

**ppcI是一個const不能modify,但*pi並不是const可修改它我覺並沒有什麼錯。
不能因為它們兩個是指向同一個個int,就禁止const轉換,真的很奇怪。
如按這樣的邏輯,下面的const轉換應該也不可以:
int i;
const int *cpi= &i;// this should not be allowed because later attempts
     // to perform the assignment "i = 0;" would
     // modify the value "*pci" that was declared as
     // being constant.
作者 : sflam(Raymond)討論區板主 Visual C++ .NET卓越專家VC++一代宗師新手入門優秀好手資訊類作業求救頂尖高手C++一代宗師貼文超過4000則
[ 貼文 4945 | 人氣 9172 | 評價 32290 | 評價/貼文 6.53 | 送出評價 142 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2013/1/9 下午 09:18:53
這個問題在本討論區曾經出現過.
http://www.programmer-club.com.tw/pc2020v5/forum/ShowSameTitleN.asp?board_pc2020=c&id=31966
作者 : sunyear(coco) VC++卓越專家C++頂尖高手貼文超過2000則
[ 貼文 2421 | 人氣 1485 | 評價 6060 | 評價/貼文 2.5 | 送出評價 5 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2013/1/10 下午 03:11:38
>這個問題在本討論區曾經出現過.
>http://www.programmer-club.com.tw/pc2020v5/forum/ShowSameTitleN.asp?board_pc2020=c&id=31966
太神奇了!2006年的貼文都能記得,還把它挖出來!
更驚奇的是那個議題我也參了一腳^^
應該實在太多文章,我沒全看,以為只是討論const的語法和語義的討論。
(我的發言也都是聚焦在語法和語義)
睜大眼從頭往下看,真的找到一篇Raymond的相關貼文:
>const int i = 10;
>  int *p;
>  const int **ppci = &p; /* int** -> const int**. ??? */
>  *ppci = &i; /* const int* -> const int* */
>  *p = 20;
這時 const int i被*p = 20;修改了!
所以const int **ppci = &p;編譯器把它擋了下來。
這個例子比微軟的這一篇好:
http://support.microsoft.com/kb/87020/en-us
至少,一個原始的const物件被修改了,總是不太對的事。
但我還是有意見:
const 在C時代,比較徧向"不可修改"或不可變的意思。
從這個觀點,我同意type **不應該隱性的被轉成const type **(理由如Raymond的例子)
但在C++裡,const還多了個"保護"或"聲名我不會修改指定物件"的功能。
而這新增的意義,我覺得還大過原來C的"不可修改"意義。
總的來說C++的const是比較徧向 modified right而不是該const 物件內容"絶對"不可修改。
(想要靠const來防止物件內容"絶對"不可修改,事實上也"絶對"辦不到)
例如const 的成員函式,表示該函式不會修改資料成員,不是資料成員不可修改。
又例如func(const char *s2);
程式員可以確認func不會修改s2的字串內容,但這不表示s2內容是不可改的,只是func沒有modified right。
這個constant的加強功能,卻因C++想要確保一個原始const的物件(絻對不可更改的物件).
不被轉了兩個彎後意外的被修改而破功。
其實const 物件,在C/C++這種有底層執行能力的語言是很難真正保證不被修改的。與其在小地方計較不如在大原則
著眼(不要搞特例)。
例如這例子:
>const int i = 10;
>  int *p;
>  const int **ppci = &p; /* int** -> const int**. ??? */
>  *ppci = &i; /* const int* -> const int* */
>  *p = 20;
int **隱性轉成const int **通例應該可隱性轉換,不要變成特例。
理由是用modified right的觀點來看const:
i宣告為const,所以i沒有修改i內容的權利。
p宣告不是const int的指標,所以它就有修改*p的權利。
但既然const int **ppci = &p; 轉型為const int,那麼ppci就沒有修改**ppci的權利。
雖然這個例子,導致了一個絶對不可修改的int內容被修改,但我覺得還可以接受(C/C++本來就不是保證安全的語言)。
因這是程式員的錯誤造成(雖然const有使得編譯階段可以抓出類似的錯功能,但本來就做不到100%)
反而是type **不能隱性轉型為const type **,我無法接受。
例如:
void fun(const int **ppObj){}

int main()
{
int **ppi= new int *[10];
fun(ppi);//不能 int ** 隱轉 const int **
}
程式的原意ppi[n]->指向的int內容不是const,但不希望fun修改它。
func也聲明了它不會修改,所以很OK。
這是一個正常的應用,但卻被C++編譯器擋了下來
而且還很難解 :(
為了能在編譯階段,多一點點抓到錯誤的機會卻令正常的應用難以運作,實在很難接受。
作者 : sflam(Raymond)討論區板主 Visual C++ .NET卓越專家VC++一代宗師新手入門優秀好手資訊類作業求救頂尖高手C++一代宗師貼文超過4000則
[ 貼文 4945 | 人氣 9172 | 評價 32290 | 評價/貼文 6.53 | 送出評價 142 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2013/1/10 下午 10:12:33
>const 在C時代,比較偏向'不可修改'或不可變的意思。

const 在 C 語言裡更傾向于 read-only 的意思, 而不是真正的 constant.

〔例1〕
  const int ci = 10;
  int array[ci] = { 0 }; /* C++ Okay, C error */

〔例2〕
  int i;
  const int ci = 10;

  switch (i)
  {
    case ci: /* C++ Okay, C error */
      break;
    ...
  }

〔例3〕
  const int ci; /* C Okay, C++ error */

例1 及 例2 說明了為什麼 C 程式員用 #define 而不用 const.
例3 是說, 在 C 語言裡, const 物件可以不必初始化.

上面的例子說明了在 C 語言裡, 'const' 的作用並不大, const 的變數跟一般的變數沒有太大不同, C 語言並不對 const 物件做特別處理.
 
這是有歷史上的因素的. 在 C 語言的發展史上, const 是在制定 C89 時才新增的關鍵字, 在之前的 K&R C 語言裡, 根本沒有 const 這個東西. 而 C++ 語言在 1983 年創建的時候就有了 const 了. 所以 'const' 最先出現在 C++, 後來才「向後移植」到 C 語言上, 但在語意上, 這兩者是互不兼容的, 上述的諸例是其一; 另外, 在 C 語言裡, const file scope 物件是 external linkage, 但在 C++, 它是 internal linkage.

作者 : sunyear(coco) VC++卓越專家C++頂尖高手貼文超過2000則
[ 貼文 2421 | 人氣 1485 | 評價 6060 | 評價/貼文 2.5 | 送出評價 5 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2013/1/11 上午 12:25:52
>>const 在C時代,比較偏向'不可修改'或不可變的意思。
>const 在 C 語言裡更傾向于 read-only 的意思, 而不是真正的 constant.
好像是一樣的意思^^

>上面的例子說明了在 C 語言裡, 'const' 的作用並不大, const 的變數跟一般的變數沒有太大不同
>, C 語言並不對 const 物件做特別處理.
很早之前用Cross C寫firmware常用const來把關電不可消失的資料放在ROM。
所以const之於C還是有它的功能。但因用const來控制ROM資料不是那麼的"明示"性;
所以後來的Cross C Compiler都另增關鍵字來控制ROM上的資料。(但並不是C標準)

回頭談type **不能隱轉const type **的問題。
我覺得C++這一規定是去小害就大害。為了檢出一個程式上的錯誤卻卡住一個正常const隱轉的應用,
很得不償失!
我現在只能暫時這樣跳過這個問題:
void fun(const int **ppObj){}

int main()
{
int **ppi= new int *[10];
fun((const int **)ppi);//不能隱轉只好顯轉
}
不知道有沒有更好的辦法?
作者 : sflam(Raymond)討論區板主 Visual C++ .NET卓越專家VC++一代宗師新手入門優秀好手資訊類作業求救頂尖高手C++一代宗師貼文超過4000則
[ 貼文 4945 | 人氣 9172 | 評價 32290 | 評價/貼文 6.53 | 送出評價 142 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2013/1/11 上午 02:11:45
>>>const 在C時代,比較偏向'不可修改'或不可變的意思。
>>const 在 C 語言裡更傾向于 read-only 的意思, 而不是真正的 constant.
>好像是一樣的意思^^

完全不一樣的意思. 「真正的 constant」表示它可以用在 constant expression 裡.

>很早之前用Cross C寫firmware常用const來把關電不可消失的資料放在ROM。
>所以const之於C還是有它的功能。但因用const來控制ROM資料不是那麼的'明示'性;
>所以後來的Cross C Compiler都另增關鍵字來控制ROM上的資料。(但並不是C標準)

Embedded C 是 C 語言的 extension, C 語言標準的內容主要是針對 hosted environment, freestanding environment 如 embedded system 不完全適用.


>回頭談type **不能隱轉const type **的問題。
>我覺得C++這一規定是去小害就大害。為了檢出一個程式上的錯誤卻卡住一個正常const隱轉的應用,

因為你要的根本就不是正常的隱轉. 正常的隱轉是:
T ** --> const T* const * (或 T const* const*).


>很得不償失!
>我現在只能暫時這樣跳過這個問題:
>void fun(const int **ppObj){}

改成:
  void fun(const int* const *ppObj) {}

>
>int main()
>{
>int **ppi= new int *[10];
>fun((const int **)ppi);//不能隱轉只好顯轉

不需 cast:
  fun(ppi);

>}
>不知道有沒有更好的辦法?


作者 : sflam(Raymond)討論區板主 Visual C++ .NET卓越專家VC++一代宗師新手入門優秀好手資訊類作業求救頂尖高手C++一代宗師貼文超過4000則
[ 貼文 4945 | 人氣 9172 | 評價 32290 | 評價/貼文 6.53 | 送出評價 142 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2013/1/11 上午 03:37:56
>因為你要的根本就不是正常的隱轉. 正常的隱轉是:
>T ** --> const T* const * (或 T const* const*).

更正一下:

正常的隱轉是:
  T ** --> T * const *

因為 T* 可以隱轉為 const T*, 如果 T 是 int* 的 typedef, 那 const T* 實際上就是 int* const*.

你的程式可以這麼寫,
  typedef int* PINT;

  void fun(const Pint *ppObj){}

  int main()
  {
    Pint *ppi= new PINT[10];
    fun(ppi);
  }

作者 : sunyear(coco) VC++卓越專家C++頂尖高手貼文超過2000則
[ 貼文 2421 | 人氣 1485 | 評價 6060 | 評價/貼文 2.5 | 送出評價 5 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2013/1/11 上午 10:41:03
>正常的隱轉是:
>  T ** --> T * const *
我所謂的"正常"是指C++的非const物件可以隱性轉換為const物件。
T **-->T * const *或 const T ** 應該要都可以才對。


>因為 T* 可以隱轉為 const T*, 如果 T 是 int* 的 typedef, 那 const T* 實際上就是 int* const*.
>你的程式可以這麼寫,
>  typedef int* PINT;
>  void fun(const Pint *ppObj){}
>
>  int main()
>  {
>    Pint *ppi= new PINT[10];
>    fun(ppi);
>  }
因為要保護不被fun修改的是int不是int *,所以...
不過這給我靈感,fun多加一個int *保護也沒什麼不好,所以可以改成這樣:
void fun(const int * const *ppObj){}
int main()
{
Pint *ppi= new PINT[10];
fun(ppi);
}
在我的應用這樣是OK的,但還是覺得T **--> const T **應該要可以隱轉比較好
 板主 : simula
 > C++ - 討論區
 - 最近熱門問答精華集
 - 全部歷史問答精華集
 - C++ - 知識庫
  ■ 全站最新Post列表
  ■ 我的文章收藏
  ■ 我最愛的作者
  ■ 全站文章收藏排行榜
  ■ 全站最愛作者排行榜
  ■  月熱門主題
  ■  季熱門主題
  ■  熱門主題Top 20
  ■  本區Post排行榜
  ■  本區評價排行榜
  ■  全站專家名人榜
  ■  全站Post排行榜
  ■  全站評價排行榜
  ■  全站人氣排行榜
 請輸入關鍵字 
  開始搜尋
 
Top 10
評價排行
C++
1 Raymond 13050 
2 青衫 4760 
3 simula 4690 
4 coco 4030 
5 白老鼠(Gary) 3670 
6 ozzy 2540 
7 Ben 2250 
8 Anderson 1960 
9 windblown 1650 
10 Kenny 1560 
C++
  專家等級 評價  
  一代宗師 10000  
  曠世奇才 5000  
  頂尖高手 3000  
  卓越專家 1500  
  優秀好手 750  
Microsoft Internet Explorer 6.0. Screen 1024x768 pixel. High Color (16 bit).
2000-2019 程式設計俱樂部 http://www.programmer-club.com.tw/
0.171875