根据我的小测试,这段代码可行.但是,它有未定义的行为吗?通过使用const_cast修改const对象导致我之前测试中的运行时访问违规,但我不记得它们是如何不同的.那么,这里根本没有错吗?
// test.h
#pragma once
#include <boost/array.hpp>
typedef boost::array<int,100000> bigLut_t;
extern const bigLut_t constBigLut;
Run Code Online (Sandbox Code Playgroud)
// test.cpp
#include "test.h"
bigLut_t& initializeConstBigLut()
{
bigLut_t* pBigLut = const_cast<bigLut_t*>( &constBigLut );
for(int i = 0; i < 100000; ++i) {
pBigLut->at(i) = i;
}
return const_cast<bigLut_t&>(constBigLut);
}
const bigLut_t constBigLut = initializeConstBigLut();
Run Code Online (Sandbox Code Playgroud)
// const_test.cpp
#include <iostream>
#include "test.h"
void main()
{
for(int i = 0; i < 100; ++i) {
std::cout << constBigLut[i] << std::endl;
}
system("pause");
}
Run Code Online (Sandbox Code Playgroud)
(请注意,sizeof(bigLut_t)太多而无法放入堆栈.)
编辑:我实际上喜欢ybungalobill的小评论中的想法最适合初始化这些大对象的方法:
// test.h
#pragma once …Run Code Online (Sandbox Code Playgroud) 以下两个函数产生不同的程序集,这告诉我它们是不同的.有人可以告诉我他们的不同之处是什么?并且函数本地静态变量初始化在func2线程安全与否?如果答案取决于编译器,我想知道最常见的编译器如何使用func2.
int func1(int val)
{
const auto impl = [](int v)
{
return v * 10;
};
return impl(val);
}
int func2(int val)
{
static const auto impl = [](int v)
{
return v * 10;
};
return impl(val);
}
Run Code Online (Sandbox Code Playgroud) 以下函数是否是线程安全的?如果它不是线程安全的,那么实际上是否有任何开销使funImpl非静态?或者编译器是否实际内联函数对象函数并完全跳过创建函数对象?
int myfun(std::array<int, 10> values)
{
static const auto funImpl = [&]() -> int
{
int sum = 0;
for (int i = 0; i < 10; ++i)
{
sum += values[i];
}
return sum;
};
return funImpl();
}
Run Code Online (Sandbox Code Playgroud)
编辑:我编辑了以下功能签名:
int myfun(const std::array<int, 10>& values)
Run Code Online (Sandbox Code Playgroud)
至:
int myfun(std::array<int, 10> values)
Run Code Online (Sandbox Code Playgroud)
所以我很清楚我不是在询问值的踏板安全性,而是函数局部静态变量funImpl的线程安全性.
一些简单的问题.
const int gFirst;
const int gSecond;
struct Data
{
static int First;
static int Second;
int first;
int second;
};
Data data;
Run Code Online (Sandbox Code Playgroud)
是否保证以下陈述是正确的?
&gFirst < &gSecond &Data::First < &Data::Second &data.first < &data.second到底发生了什么?
#include <boost/array.hpp>
#include <boost/assign/list_of.hpp>
struct Toy {
int m_data[100000];
};
struct Box {
Box()
: m_toys( boost::assign::list_of( Toy() )( Toy() )( Toy() ) )
{}
boost::array<Toy,3> m_toys;
};
void main()
{
Box* box = new Box; // This causes stack overflow
}
Run Code Online (Sandbox Code Playgroud) 这段代码似乎有用,但我是否正确使用了InterlockedIncrement函数?m_count的正确内存对齐是我主要关心的问题.假设我们在x86-64系统上并编译一个64位应用程序(如果重要的话).顺便说一句,为了我的实际目的,我不能将m_count声明为volatile long,然后使用InterlockedIncrement(&m_count); 但它必须是指向堆中数据的指针.
#include <Windows.h>
#include <malloc.h>
class ThreadSafeCounter {
public:
ThreadSafeCounter()
{
// Are those arguments for size and alignment correct?
void* placement = _aligned_malloc( sizeof(long), sizeof(long) );
m_count = new (placement) long(0);
}
~ThreadSafeCounter()
{
_aligned_free( const_cast<long*>(m_count) );
}
void AddOne()
{
InterlockedIncrement(m_count);
}
long GetCount()
{
return *m_count;
}
private:
volatile long* m_count;
};
Run Code Online (Sandbox Code Playgroud) 必须将非整数常量(显式或隐式)转换为整数类型,使其在常量表达式中是合法的.因此,以下代码是合法的:
Run Code Online (Sandbox Code Playgroud)const double Size = 11.0; char chArray[(int)Size];
至少在VC++ 10.0上,第二行产生:"错误C2057:预期的常量表达式".那么它在某些其他编译器上是合法的还是msdn页面完全错了?
我尝试使用Visual Studio 2012 RC和英特尔C++编译器XE 12.1进行编译.如果您尝试使用其他编译器,我将不胜感激.在代码中查看我的评论,真正体会到这个bug的奇怪之处.有谁知道发生了什么,我应该在哪里提交有关此问题的错误报告?
// File: NamedSameA.h
#pragma once
Run Code Online (Sandbox Code Playgroud)
// File: NamedSameA.cpp
#include <vector>
#include "NamedSameA.h"
struct NamedSame // Rename this class to something else to make the program work
{
std::vector<int> data;
// Comment out the previous line or change
// the data type to int to make the program work
};
static NamedSame g_data; // Comment out this line to make the program work
Run Code Online (Sandbox Code Playgroud)
// File: NamedSameB.h
#pragma once
void test();
Run Code Online (Sandbox Code Playgroud)
// File: NamedSameB.cpp
#include <vector>
#include …Run Code Online (Sandbox Code Playgroud)