![](/img/trans.png)
[英]What cause undefined behavior when converting from unsign int to sign int and print it out
[英]Are there any undefined behavior issues when moving data into a function and then back out to where it came from?
考慮以下功能:
std::vector<int> pushIt(std::vector<int> v){
v.push_back(10);
return v;
}
int main(){
std::vector<int> vec;
vec = pushIt(std::move(vec));
}
我的假設是向量移動到函數中,修改並移回其原始位置。 這應該導致類似的行為,因為它作為非const引用傳遞。 這似乎是非常有效的行為,但同事擔心未定義的行為。 這里有什么我想念的嗎?
我想這樣做是因為當前的功能
void currentPushIt(std::vector<int>& v){
v.push_back(10);
}
在代碼審查中導致了很多問題,因為人們忽略了對currentPushIt(v)
的無辜調用可能使迭代器無效的事實。 讓他們寫v=pushIt(std::move(v))
應該喚醒他們不會犯同樣的錯誤。
根據1.9p15,在執行函數體之前,對與參數關聯的值計算和副作用進行排序。 因此,當您輸入pushIt
,源vec
已被移除。 然后在執行pushIt
之后對賦值進行pushIt
,因為您實際上正在調用用戶定義的運算符vector::operator=
:
vec.operator=( // sequenced after
pushIt( // the evaluation of this, which is sequenced after
std::move( // the evaluation of this
vec)))
所以你的代碼很好。
你的同事擔心是沒有理由的,所示的片段不會受到不確定行為的影響 。
由於std::vector
是一個類,所寫的片段等同於下面的內容,因為函數參數在調用函數之前必須有一個值,它相當於首先調用std::move
,然后是pushIt
,后來是vec.operator=
。
以這種方式查看時,很明顯,編寫這樣的代碼實際上是安全的。
vec.operator= (pushIt (std::move (vec));
a = do_something (a);
我遇到過那些擔心這些片段的開發者,因為=
不是序列點 ; 如果do_something
修改a
,左側會發生什么?
長話短說; 沒關系。 即使我們不知道將評估左側和右側的順序,但在正確性方面它是明確定義的。
=
的左側是左值 ,可以看作某個值最終的位置。 無論存儲在此位置的值,實際位置將始終相同。
在這種情況下,右側將從vec
移開。 這無疑會改變vec
的價值,但它不會改變vec
的位置; 所以右側的結果將被正確地分配到它應該的位置。
注意:實際分配是按順序排列的,在發生這種情況之前必須評估lhs和rhs (即在將rhs的值分配給lhs的位置產量之前),但是未設置lhs和rhs的評估順序在石頭上。
將數據移入函數然后返回到它來自何處時,是否存在任何未定義的行為問題?
沒有。
函數參數被評估為“在序列之前”功能評估。 分配是在“右側評估”之后“排序”。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.