标签: elision

如果我的所有导入都来自我自己的文件,我是否需要使用 TypeScript 3.8 的“导入类型”功能?

我有一个types.ts定义一些类型的简单文件:

export interface MyInterface {
   // ...
}

export const enum MyEnum {
   // ...
}

export type MyType = {
  // ...
}
Run Code Online (Sandbox Code Playgroud)

我看了一下新功能,import type最新的打字稿这里。据我所知,它旨在解决从 .js 文件导入时似乎主要发生的特定问题。

我可以使用importandimport type语句导入我的类型。两者似乎工作得同样好。问题是我应该更愿意import type更明确地帮助我避免一些理论上的边缘问题,还是我可以只是import为了简单而使用并依赖于import elision从编译的代码中删除这些问题?

换句话说:在这里使用有什么好处,import type还是应该用于特定情况以解决import elision缺点?

import module typescript elision typescript3.8

30
推荐指数
1
解决办法
9182
查看次数

这是“省略失败”语言规定的吗?

考虑以下代码:

#include <utility>
#include <string>

int bar() {
    std::pair<int, std::string> p { 
        123, "Hey... no small-string optimization for me please!" };
    return p.first;
}
Run Code Online (Sandbox Code Playgroud)

(简化感谢@ Jarod42 :-) ...)

我希望该功能可以简单地实现:

bar():   
        mov eax, 123
        ret
Run Code Online (Sandbox Code Playgroud)

但是,实现调用operator new(),std::string用我的文字构造 an ,然后调用operator delete(). 至少 - 这就是 gcc 9 和 clang 9 所做的(GodBolt)。这是铛的输出:

bar():                                # @bar()
        push    rbx
        sub     rsp, 48
        mov     dword ptr [rsp + 8], 123
        lea     rax, [rsp + 32]
        mov     qword ptr [rsp …
Run Code Online (Sandbox Code Playgroud)

c++ stdstring compiler-optimization language-lawyer elision

7
推荐指数
1
解决办法
219
查看次数

我可以告诉我的编译器忽略语句或函数的副作用吗?

假设我的代码具有以下功能:

inline int foo() {
    bar();
    int y = baz();
    return y;
}
Run Code Online (Sandbox Code Playgroud)

并假设bar()baz()有副作用。

如果我写:

int z = foo();
printf("z is %d\n", z);
Run Code Online (Sandbox Code Playgroud)

那么显然都bar()baz()必须执行。但如果我写:

foo();
Run Code Online (Sandbox Code Playgroud)

并且不使用返回值,调用的唯一原因baz()是它的副作用。

有没有一种方法可以告诉我的编译器(对于:GCC、clang、MSVC、Intel 中的任何一个),例如“baz()为了决定是否优化它,您可能会忽略它的副作用”?或者“为了决定是否优化它,您可能会忽略此指令的副作用”?

这个问题是针对 C 和 C++ 提出的,但可能与各种过程语言相关。让我们使用 C++,因为这是我现在最常用的。

笔记:

  • bar()baz()不在我的控制之下。
  • 的签名foo()不得更改。当然baz(),如果我愿意,我可以使用一些代理并懒惰地应用;或者只是为不使用的情况编写一个不同的函数y。这不是我要问的。

c++ side-effects compiler-optimization compiler-options elision

4
推荐指数
1
解决办法
114
查看次数

即使构造函数具有可观察到的副作用,标准中是否允许消除未使用对象的构造?

考虑以下代码:

#include <iostream>

struct M {
    M() { std::cout << "M\n"; }
};

template <class T>
struct Test {
    Test() { std::cout << "Test\n"; }
    inline static auto m = M{};
};
int main() {
    Test<int> t1;
    //Test t;
    //(void)&t1.m;
}
Run Code Online (Sandbox Code Playgroud)

使用最新的GCCClang打印出唯一的“测试”。但是,如果我们使用地址m(取消注释最后一行对象(void)&t1.m;)或转换Test类模板到常规(非模板)类M构造函数被调用。

C++ 标准允许这种行为吗?任何报价?

c++ language-lawyer elision

4
推荐指数
1
解决办法
56
查看次数

“explicit”关键字如何影响 C++ 复制构造函数和函数参数?

修改复制构造函数的“ explicit ”关键字可能会导致问题。\n作为函数参数传递的对象特别容易受到这些问题的影响。

\n

这是我的代码:

\n
#include <iostream>\n#include <string>\n\nclass Pig{\npublic:\n    std::string _name;\npublic:\n    Pig(std::string n) : _name(n) {}\n    //~Pig() = default;\n    explicit Pig(const Pig &other) {\n        std::cout << "copy ctor!" << std::endl;\n        this->_name = other._name;\n    }\n};\n\nvoid show(Pig p) {\n    std::cout << p._name << std::endl;\n}\n\nint main() {\n    Pig pig{std::string("hello")};\n    show(Pig{pig});     // no pass\n    // show(Pig(pig));  // no pass\n    return 0;\n}\n
Run Code Online (Sandbox Code Playgroud)\n

编译器版本:g++(Ubuntu 9.4.0-1ubuntu1~20.04.1)9.4.0。

\n

上面提到的代码不能用c++14 或更低版本编译,\n但用c++17 及更高版本编译成功。

\n

这是编译器的错误:

\n
test.cpp: In function \xe2\x80\x98int main()\xe2\x80\x99:\ntest.cpp:22:7: error: cannot …
Run Code Online (Sandbox Code Playgroud)

c++ compiler-errors explicit copy-elision elision

4
推荐指数
1
解决办法
124
查看次数