过去几天我一直在研究这个问题,到目前为止,除了教条论点或对传统的诉求之外,我还没有真正找到任何令人信服的东西(即"它是C++方式!").
如果我正在创建一个对象数组,使用时有什么令人信服的理由(除了易用性):
#define MY_ARRAY_SIZE 10
// ...
my_object * my_array=new my_object [MY_ARRAY_SIZE];
for (int i=0;i<MY_ARRAY_SIZE;++i) my_array[i]=my_object(i);
Run Code Online (Sandbox Code Playgroud)
过度
#define MEMORY_ERROR -1
#define MY_ARRAY_SIZE 10
// ...
my_object * my_array=(my_object *)malloc(sizeof(my_object)*MY_ARRAY_SIZE);
if (my_object==NULL) throw MEMORY_ERROR;
for (int i=0;i<MY_ARRAY_SIZE;++i) new (my_array+i) my_object (i);
Run Code Online (Sandbox Code Playgroud)
据我所知,后者比前者更有效(因为你没有不必要地将内存初始化为一些非随机值/调用默认构造函数),唯一的区别就在于你清理了一个:
delete [] my_array;
Run Code Online (Sandbox Code Playgroud)
另一个你清理:
for (int i=0;i<MY_ARRAY_SIZE;++i) my_array[i].~T();
free(my_array);
Run Code Online (Sandbox Code Playgroud)
我出于一个令人信服的理由.上诉的事实,这是C++(不是C),因此malloc而free不应使用不-据我可以告诉- 引人注目的一样,因为它是教条主义.是否有一些我缺少的东西new []优于malloc?
我的意思是,就我所知,你根本不能使用new []- 根本没有 - 创建一个没有默认的无参数构造函数的数组,而这个malloc方法可以这样使用.
g++ --version 收益率:
g++.exe (x86_64-posix-seh-rev0, Built by MinGW-W64 project) 4.9.1
Copyright (C) 2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Run Code Online (Sandbox Code Playgroud)
程序:
#include <memory>
#include <type_traits>
#include <unordered_map>
static_assert(!std::is_copy_constructible<std::unordered_map<int,std::unique_ptr<int>>>::value,"Copyable");
int main () { }
Run Code Online (Sandbox Code Playgroud)
编译结果:
.\unorderedmapcopyable.cpp:5:1: error: static assertion failed: Copyable
static_assert(!std::is_copy_constructible<std::unordered_map<int,std::unique_ptr<int>>>::value,"Copyable");
^
Run Code Online (Sandbox Code Playgroud)
相关标准:
为语句X u(a)和X u=a是有效的,对于一些容器类型X,它包含类型T,其中a是类型的值X: …
显然,在函数指针和对象指针之间进行转换是一般意义上的未定义行为,但POSIX(请参阅:dlsym)和WinAPI(请参阅:GetProcAddress)需要这样做.
鉴于此,并且鉴于这样的代码无论如何都是针对特定于平台的API,它对于函数指针和对象指针不兼容的平台的可移植性实际上是无关紧要的.
但是--Wableantic无论如何警告它,并且#pragma GCC diagnostic ignored "-Wpedantic"没有效果:
warning: ISO C++ forbids casting between pointer-to-function and pointer-to-object [enabled by default]
Run Code Online (Sandbox Code Playgroud)
我希望保持-Wpedantic启用,因为它确实提供了良好的警告,但我不希望在关于对象指针强制转换的函数指针的无关警告中出现真正的警告和错误.
有没有办法实现这个目标?
在Windows上运行GCC 4.8.0(MinGW):
gcc (rubenvb-4.8.0) 4.8.0
Run Code Online (Sandbox Code Playgroud)
代码示例
#include <windows.h>
#include <iostream>
int main (void) {
std::cout << *reinterpret_cast<int *>(GetProcAddress(LoadLibraryA("test.dll"),"five")) << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
发射(使用-Wpedantic):
warning_demo.cpp: In function 'int main()':
warning_demo.cpp:7:87: warning: ISO C++ forbids casting between pointer-to-funct
ion and pointer-to-object [enabled by default]
std::cout << *reinterpret_cast<int *>(GetProcAddress(LoadLibraryA("test.dll"), …Run Code Online (Sandbox Code Playgroud) 我发现LLVM中有一些内在函数,比如llvm.memcpy,llvm.va_start.
但是我不知道为什么它们存在以及为什么其他人不存在.例如,由于memcpy原型是在里面string.h,为什么其他功能,例如strcpy,不被视为内在的?
我注意到在某些情况下前端可能会生成特殊的内部函数调用.对于一个简单的案例:
#include<string.h>
int foo(void){
char str[10] = "str";
return 0;
}
Run Code Online (Sandbox Code Playgroud)
fooclang生成的llvm IR 是:
define i32 @foo() #0 {
entry:
%str = alloca [10 x i8], align 1
%0 = bitcast [10 x i8]* %str to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %0, i8* getelementptr inbounds ([10 x i8]* @foo.str, i32 0, i32 0), i64 10, i32 1, i1 false)
ret i32 0
}
Run Code Online (Sandbox Code Playgroud)
llvm.memcpy在IR中调用,但不在源代码中.但前端是否可以在没有此内在函数的情况下生成LLVM IR? …
考虑:
class test {
private:
int n;
int impl () const noexcept {
return n;
}
public:
test () = delete;
test (int n) noexcept : n(n) { }
int get () const noexcept(noexcept(impl())) {
return impl();
}
};
Run Code Online (Sandbox Code Playgroud)
海湾合作委员会说不
test.cpp:27:43: error: cannot call member function 'int test::impl() const' with
out object
int get () const noexcept(noexcept(impl())) {
Run Code Online (Sandbox Code Playgroud)
同理:
test.cpp:27:38: error: invalid use of 'this' at top level
int get () const noexcept(noexcept(this->impl())) {
Run Code Online (Sandbox Code Playgroud)
和
test.cpp:31:58: error: invalid use of …Run Code Online (Sandbox Code Playgroud) 更具体地说,为什么typedef在许多情况下具有多个不同名称的同一事物,以及为什么typedef指针类型(有时模糊逻辑)?
例如:
typedef const WCHAR *LPCWSTR, *PCWSTR;
那是什么意思?
我知道,现代C++编译器和处理器通常会通过重新排序指令来执行某些优化,以获得更好的性能.
C++ 11 在关系之前引入了一个顺序.如果指令在程序顺序的指令A之前到来B,我们说之前A是顺序的 B.
int data = 0;
bool ready = 0;
// A is sequenced before B
data = 6; // A
ready = true; // B
Run Code Online (Sandbox Code Playgroud)
C++ 11还定义了在关系之前排序的要求.
给定任何两个评估A和B,如果A在B之前被排序,那么A的执行应该在B的执行之前.
这让我很困惑.对我而言,它与无序执行相冲突,因为重新排序可能会破坏上述所需的属性.例如,当商店ready发生在商店之前data.
上面的定义是否会停止指令重新排序?(我很确定不是.但是我错过了什么?)
我一直在研究一个项目,随着它的成长,我意识到两个不能连接在一起的部分是相互依赖的.
我们将这两个部分称为a.exe和b.dll.b.dll提供了一个允许a.exe检索数据的实现,但我希望它是自己的独立程序集,以便可以轻松更改它以使a.exe与不同的数据源通信.
但是,虽然需要a.exe来引用b.dll,但b.dll需要多个函数,这些函数是a.exe不可分割的一部分.
因为我一直在编译 - 测试 - 因为我一直在编写这个项目,a.exe和b.dll都存在,我可以针对a.exe编译b.dll而针对b.dll编译a.exe ,但我怎么能/可以从源头重建这两个?
在Windows中,是否无法获取文件指针的当前位置?
例如,如果我使用SetFilePointer,并且我想确定文件中的位置,文件指针在搜索后被清除?
我有以下代码:
do
{
doStuffP1();
if (test)
{ goto skip_increment;
}
dostuffP2();
skip_increment:
// 1; // Only works if I remove the comment at line start.
} while (loop);
Run Code Online (Sandbox Code Playgroud)
哪个不编译(VC++ 2010)有这个错误:
file_system_helpers.cpp(109) : error C2143: syntax error : missing ';' before '}'
Run Code Online (Sandbox Code Playgroud)
如果我将其更改为:
skip_increment:
1;
Run Code Online (Sandbox Code Playgroud)
它编译(并且有效).
这真的是C++语法的限制吗?