我读过这篇文章:未定义的行为和序列点,但我不知道,是否是UB.
请考虑以下示例:
#include <iostream>
class op {
public:
explicit op(int x) {
std::cout << "x: " << x << std::endl;
}
op & operator + (const op & /* other */) {
return *this;
}
};
int main(int /* argc */, char * /* argv */ []) {
int x = 0;
op o = op(x++) + op(x++) + op(x++);
std::cout << "res: " << x << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我希望这样的输出(或基于评估顺序的输出的一些排列):
x: 0
x: 1
x: 2 …Run Code Online (Sandbox Code Playgroud) 我正在研究一些遗留代码而且遇到了一些我不确定是否安全的东西 - 事实上我很确定它是未定义的,但我不完全确定为什么(或多或少是一种不好的感觉).
由于某种原因,这段代码有一个类,我们称之为A.类A有一个重载的预增量运算符(++),似乎对其中包含的指针的值进行一些操作(我们称之为指针B).
我找到了一个函数调用,其中用户传入A,并且在使用已经过载的预增量运算符时使用了指针B的解引用副本.
foo(++A, *B);
Run Code Online (Sandbox Code Playgroud)
由于A的预增量修改了B指向的值,并且B被解除引用并在同一个调用中用作参数...是否有问题或者我应该这样离开?
很抱歉,如果这听起来很混乱 - 代码太复杂而无法粘贴,但我尽力解释这种情况.如果需要,我会制作一些代表情况的假代码,但我希望它清楚.
另外,我知道这个代码的设计很难分别传入已包含在A中的参数,但我想了解除此之外是否存在实际问题.
有人可以引用C++标准的相应段落,该段落表示在以下情况中未指定std::string构造和foo()调用的顺序:
std::string().append(foo());
Run Code Online (Sandbox Code Playgroud)
我知道有5.2.2.8,但它说明了函数参数,而不是相同序列点之间的几个函数调用:
函数参数的评估顺序未指定
这里我有一个命名函数max(a,b)来获取两个最大数量.我发现变量a和b使用的值printf() 在执行后是不同的
printf("maxab()=%d after max: a=%d b=%d \n",max(a++,b++),a,b);
Run Code Online (Sandbox Code Playgroud)
当a和b是Global variables和Local variables.以下是我的代码:
#include<stdio.h>
int max(int a,int b)
{
if(a>b)
{
//printf("In func max():%d %d \n",a,b);
return a;
}
else {
//printf("In func max():%d %d \n",a,b);
return b;
}
}
void jubu_test(void)
{
int a=1;
int b=2;
printf("maxab()=%d after max: a=%d b=%d \n",max(a++,b++),a,b); //a=2,b=3
}
int c=2;
int d=1;
void quanju_test(void)
{
printf("maxcd()=%d c=%d d=%d \n",max(c++,d++),c,d); //c=2,d=1 …Run Code Online (Sandbox Code Playgroud) 函数在以下表达式中调用的顺序是什么:
a = f1(23, 14) * f2(12/4) + f3();
Run Code Online (Sandbox Code Playgroud)
它取决于编译器吗?
我有这个代码:
template<typename ...T>
struct Test
{
void call(string str)
{
abc(get<T>(str)...);
}
template<typename U>
string get(string& inp)
{
string ret{ inp[0] };
inp.erase(0, 1);
cout << ret << endl; // first "a", next "b", next "c" - everything is ok
return ret;
}
void abc(string a, string b, string c)
{
cout << a << " " << b << " " << c << endl; // "b c a" - why?
}
};
Run Code Online (Sandbox Code Playgroud)
我这样称呼它:
Test<int, bool, float> test;
test.call("abc"); …Run Code Online (Sandbox Code Playgroud) 据我们所知,函数参数评估顺序不是由c ++标准定义的.
例如:
f(g(), h());
Run Code Online (Sandbox Code Playgroud)
所以我们知道它是未定义的.
我的问题是,为什么c ++标准不能从左到右定义评估顺序?
我正在制作一个简单的命令行Hangman游戏.
void Hangman::printStatus()
{
cout << "Lives remaining: " << livesRemaining << endl;
cout << getFormattedAnswer() << endl;
}
string Hangman::getFormattedAnswer()
{
return getFormattedAnswerFrom(correctAnswer.begin(), correctAnswer.end());
}
string Hangman::getFormattedAnswerFrom(string::const_iterator begin, string::const_iterator end)
{
return begin == end? "" : displayChar(*begin) + getFormattedAnswerFrom(++begin, end);
}
char Hangman::displayChar(const char c)
{
return c;
}
Run Code Online (Sandbox Code Playgroud)
(最后,如果用户已经猜到了,我会更改它以displayChar()显示一个-或一个字符,但为了简单起见,我现在只返回所有内容.)
当我从VS 2010构建并运行它时,我得到一个弹出框:
调试断言失败!
xstring线:78
表达式:字符串迭代器不可解除引用
我究竟做错了什么?
为什么以下打印出"World Hello!"?
根据我的理解,根据运算符优先级,这应该从右边开始评估.但相反,从左到右似乎是正确的.为什么是这样?
#include <iostream>
using namespace std;
char print() {
cout << "World";
return '!';
}
int main() {
cout << "Hello " << print() << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud) 我对调用 C++ 函数时函数参数的计算顺序感到困惑。我可能解释错了,所以请解释是否是这种情况。
例如,Charles Petzold 的传奇著作“Programming Windows”包含如下代码:
// hdc = handle to device context
// x, y = coordinates of where to output text
char szBuffer[64];
TextOut(hdc, x, y, szBuffer, snprintf(szBuffer, 64, "My text goes here"));
Run Code Online (Sandbox Code Playgroud)
现在,最后一个参数是
snprintf(szBuffer, 64, "My text goes here")
Run Code Online (Sandbox Code Playgroud)
它返回写入 char[] szBuffer 的字符数。它还将文本“My text go here”写入 char[] szBuffer。第四个参数是 szBuffer,它包含要写入的文本。但是,我们可以看到 szBuffer 填充在第五个参数中,告诉我们不知何故是表达式
// argument 5
snprintf(szBuffer, 64, "My text goes here")
Run Code Online (Sandbox Code Playgroud)
之前评估过
// argument 4
szBuffer
Run Code Online (Sandbox Code Playgroud)
好的。总是这样吗?评估总是从右到左进行?查看默认调用约定__cdecl:
__cdecl 调用约定的主要特点是:
参数从右向左传递,并放置在堆栈中。
堆栈清理由调用者执行。
函数名称通过在其前面加上下划线字符 '_' 来修饰。
(来源: …
我编写了一个程序来翻转彼此相邻的数组元素。例如
1, 2, 1, 2 变成 2, 1, 2, 1
我写的代码是:
#include <iostream>
template <class T>
void swap(T& a, T& b){
T temp = a;
a = b;
b = temp;
}
template <class T>
void oReverse(T* p, int size){
for(T* e = p + size; p < e; p+=1){
swap(*p, *p++);
}
}
int main(){
int arr[] = {1,2,1,2,1,2};
oReverse(arr, 6);
for(int i = 0; i < 6; i++){
std::cout << arr[i] << " ";
}
return 0;
} …Run Code Online (Sandbox Code Playgroud) 我写过这个从文本文件中读取一些数字的小解析器.
data.resize(7,datapoints); //Eigen::Matrix<float,7,-1> & data
dst = data.data();
while( fgets(buf,255,fp) != 0 && i/7 < datapoints)
{
int n = sscanf(buf,"%f \t%f \t%f \t%f \t%f \t%f \t%f",dst+i++, dst+i++,dst+i++,dst+i++,dst+i++,dst+i++,dst+i++);
i = i - 7 * (n<=0);
}
fclose(fp);
return !(datapoints == i/7);
Run Code Online (Sandbox Code Playgroud)
问题是,当我对数据执行std :: cout时,它会翻转.
数据在:
0 4 0.35763609 0.64077979 0 0 1
0 4 0.36267641 0.68243247 1 0 2
0 4 0.37477320 0.72945964 2 1 3
Run Code Online (Sandbox Code Playgroud)
data.col(3)是
0.64077979
0.68243247
0.72945964
Run Code Online (Sandbox Code Playgroud)
和data.col(4)是
0.35763609
0.36267641
0.37477320
Run Code Online (Sandbox Code Playgroud)
我无法看到为什么它将数据水平翻转的逻辑?
我创建了两个函数并将值返回到main部分.
#include <iostream>
using namespace std;
int a =8;
int g(){a++; return a-1;}
int f(){a++; return a;}
int main (){
cout << g()+f()<<endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我不是为什么输出是18而不是17.我想知道是否有人能为我详细解释这一点?谢谢你的帮助