标签: sequence-points

这个双重检查锁定修复有什么问题?

所以我看到很多文章现在声称在C++上双重检查锁定,通常用于防止多个线程尝试初始化一个懒惰的单例,被打破了.正常双重检查锁定代码如下所示:

class singleton {
private:
    singleton(); // private constructor so users must call instance()
    static boost::mutex _init_mutex;

public:
    static singleton & instance()
    {
        static singleton* instance;

        if(!instance)
        {
            boost::mutex::scoped_lock lock(_init_mutex);

            if(!instance)           
                instance = new singleton;
        }

        return *instance;
    }
};
Run Code Online (Sandbox Code Playgroud)

问题显然是行分配实例 - 编译器可以自由分配对象,然后将指针分配给它,或者将指针设置为它将被分配的位置,然后分配它.后一种情况打破了这个习惯用法 - 一个线程可以分配内存并分配指针,但在它进入休眠状态之前不运行单例的构造函数 - 然后第二个线程将看到该实例不为null并尝试返回它,即使它尚未建成.

看到了一个使用线程局部布尔值的建议并检查而不是instance.像这样的东西:

class singleton {
private:
    singleton(); // private constructor so users must call instance()
    static boost::mutex _init_mutex;
    static boost::thread_specific_ptr<int> _sync_check;

public:
    static singleton & instance()
    {
        static …
Run Code Online (Sandbox Code Playgroud)

singleton multithreading locking sequence-points double-checked-locking

5
推荐指数
1
解决办法
2210
查看次数

是"int i = x ++,j = x ++;" 法律?

我认为标题中很清楚.我对此并不完全确定,而且我无法通过谷歌找到一个好的答案(唉,我还没有致力于标准的精美艺术),所以我问:

int i = x++, j = x++;
Run Code Online (Sandbox Code Playgroud)

这个定义了吗?我很确定i = x++, j = x++;正常语句是未定义的行为是逗号运算符,它是一个序列点并且是合法的,但没有一个来源很清楚初始值设定项是以分号结束还是一旦下一个变量开始被声明,因为那不是逗号运算符,我找不到明确的答案.所以要么a)逗号结束初始化器,是一个序列点,这是有效的,或者b)它没有.这是什么?

为了排除,我知道我应该简化头痛并将其写成:

int i = x++;
int j = x++;
Run Code Online (Sandbox Code Playgroud)

并保证它已定义.我出于好奇而要求更多.

c initialization operator-precedence sequence-points

5
推荐指数
1
解决办法
433
查看次数

为什么这个未定义的行为?

为什么以下给定的表达式会调用未定义的行为?

int i = 5;
i = (i,i++,i) + 1 
Run Code Online (Sandbox Code Playgroud)

我的问题在这里受到Als问题的影响

c++ undefined-behavior sequence-points

5
推荐指数
1
解决办法
306
查看次数

java中的序列点

是否有保证的以下java代码的执行顺序:

int i = getA() + getB();
Run Code Online (Sandbox Code Playgroud)

getA()之前一直执行的getB(),因为任何一般人所期望的?

java sequence-points

5
推荐指数
1
解决办法
529
查看次数

在可变扩展中的排序

对于这个非变量的例子:

int     Func1();
double  Func2();
void    MyFunc( int, double );

int  main()
{
    MyFunc( Func1(), Func2() );
    //...
}
Run Code Online (Sandbox Code Playgroud)

它没有规定是否Func1()还是Func2()先计算,只是两者都必须做之前MyFunc()被调用.

这个测序如何与可变参数的扩展一起工作?

template < typename Func, typename ...Args >
void  MyFunc2( Func &&f, Args&& ...a )
{
    int  b[] = { f( std::forward<Args>(a) )... };
    //...
}
Run Code Online (Sandbox Code Playgroud)

假设这f是一个在第一次调用后改变其状态的函数对象.是否会f为每个段调用a?换句话说,将fa列表中的第一个项目,然后第二个项目,第三个项目等上调用,而不是随机跳过扩展列表?我们曾经在每个项目之间调用序列点吗?

c++ variadic-functions sequence-points variadic-templates c++11

5
推荐指数
1
解决办法
522
查看次数

如何使用"x = x ++"之类的东西获得VS或Xcode警告?

本着与序列点相关的未定义行为的精神,例如"x = ++ x",它是否真的未定义?,如何让编译器抱怨这样的代码?

具体来说,我使用的是Visual Studio 2010和Xcode 4.3.1,后者是OSX应用程序,并没有提醒我这一点.我甚至把VS2010上的警告发送到"全部",并且很高兴编译了这个.(为了记录,VS2010的版本在变量中添加了1,其中Xcode的版本保持变量不变.)

c visual-studio-2010 undefined-behavior sequence-points xcode4.3

5
推荐指数
1
解决办法
104
查看次数

为什么对基本类型的操作是无序的而不是不确定的顺序?

如果i是一个int,则像这样的表达式++i + ++i是未定义的行为,因为有 2 个无序的修改i。然而, ifi是一些int类似的类,++i + ++i而是具有不确定顺序的修改,因此是定义的行为(在这种情况下具有确定性结果)。是否存在对原语的操作不排序而不是不确定排序会更好的情况?如果是这样,为什么这种情况不适用于用户创建的类型?如果不是,为什么原始操作根本没有顺序?

c++ undefined-behavior sequence-points c++11

5
推荐指数
1
解决办法
316
查看次数

类似于"for(i = 1; i <= 10; printf("%d \n"; i),i ++)在C中有效且无UB吗?

以下两个代码块完全相同并实现相同的功能吗?它在运行程序时显示相同的内容,但我要感谢一些严格的解释.

for(i=1;i<=10;i++)
{
printf("%d\n",i);
}
Run Code Online (Sandbox Code Playgroud)

for(i=1;i<=10;printf("%d\n",i),i++);
Run Code Online (Sandbox Code Playgroud)

for环路期望有效C语句作为参数,不是吗?但即使我已经在StackOverflow上验证了这样的语句x+=4,y=x*2;是安全的,因为这里的逗号充当了序列点,对于在上面printf("%d\n",i),i++)for循环中作为参数传递的语句是否相同?

如果是,请费心回答由此产生的小问题:

  • comma行为是否在包含许多逗号分隔的语句中作为序列点

    函数调用如下:

    printf("Enter number\n"),scanf("%d",&number),printf("You entered %d",number);

c comma-operator sequence-points

5
推荐指数
1
解决办法
1775
查看次数

C - printf的输出说明("%d%d \n",k = 1,k = 3);

如何解释下面代码的输出:

include <stdio.h>

int main(void) {
    int k;
    printf("%d %d\n",k=1,k=3);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

Ideone Link

我的想法是1将分配给k变量然后1打印.同样3将分配给k和输出3.

预期产出

1 3
Run Code Online (Sandbox Code Playgroud)

实际产出

1 1
Run Code Online (Sandbox Code Playgroud)

我是从外推

int a;
if (a = 3) { 
    ...
} 
Run Code Online (Sandbox Code Playgroud)

等于

if (3) { 
    ... 
}
Run Code Online (Sandbox Code Playgroud)

请让我知道我哪里错了?

c printf function-calls variable-assignment sequence-points

5
推荐指数
1
解决办法
159
查看次数

(a=1)=2 在 C++98 中是未定义的行为吗?

类似的代码例如(a+=1)%=7;,其中 a 是一个int变量。

我们知道运算符+=or=不是序列点,因此我们在两个相邻的序列点之间有两个副作用。(我们这里使用的是cpp98的序列点规则)

然而,赋值运算符喜欢+==保证在赋值后返回左值,这意味着执行顺序在某种程度上是“定义的”。

那么这是一种未定义的行为吗?

c++ undefined-behavior sequence-points language-lawyer c++98

5
推荐指数
1
解决办法
115
查看次数