小编Mik*_*yke的帖子

不同的编译结果不使用C++中的C vs extern

当我在两个不同的源文件中声明一个全局变量并且只在其中一个源文件中定义它时,我得到的C++编译结果与C相比不同.请参阅以下示例:

main.c中

#include <stdio.h>
#include "func.h" // only contains declaration of void print();

int def_var = 10;

int main() {
    printf("%d\n", def_var);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

func.c

#include <stdio.h>
#include "func.h"

/* extern */int def_var; // extern needed for C++ but not for C?

void print() {
    printf("%d\n", def_var);
}
Run Code Online (Sandbox Code Playgroud)

我用以下命令编译:

gcc/g++ -c main.c -o main.o
gcc/g++ -c func.c -o func.o
gcc/g++ main.o func.o -o main
Run Code Online (Sandbox Code Playgroud)

g ++/clang ++抱怨multiple definition of def_var(这是我预期的行为,不使用extern时).gcc/clang编译得很好.(使用gcc 7.3.1和clang 5.0)

根据这个链接:

暂定定义是一种可能或可能不作为定义的声明.如果在同一翻译单元中较早或较晚发现实际的外部定义,则暂定定义仅作为声明.

所以我的变量 …

c c++ extern

11
推荐指数
2
解决办法
1012
查看次数

如何在bazel规则中获取WORKSPACE目录

我为了使用像这样的 clang 工具clang-formatclang-tidy或者生成这样编译数据库,我需要知道 .bzl 文件中的 WORKSPACE 目录。我怎样才能获得它?考虑以下示例,我只想打印工作区中所有 src 文件的完整路径:

# simple_example.bzl

def _impl(ctx):
  workspace_dir = // ---> what comes here? <---
  command = "\n".join([echo %s/%s" % (workspace_dir, f.short_path) 
                       for f in ctx.files.srcs])

  ctx.actions.write(
      output=ctx.outputs.executable,
      content=command,
      is_executable=True)


echo_full_path = rule(
    implementation=_impl,
    executable=True,
    attrs={
      "srcs": attr.label_list(allow_files=True),
    }
)
Run Code Online (Sandbox Code Playgroud)

# BUILD

echo_full_path(
    name = "echo",
    srcs = glob(["src/**/*.cc"])
)
Run Code Online (Sandbox Code Playgroud)

有没有更干净/更好的方法来做到这一点?

bazel

8
推荐指数
1
解决办法
1万
查看次数

内联汇编器的 Stringify 模板类型

我正在寻找一种通过模板函数自动执行 gcc 内联汇编调用的方法。
例如,我有以下虚拟函数将值存储到指针中。现在我专门针对不同类型的模板函数。每当代码发生变化时,我都需要针对每个专业化进行更改。

template <typename T>
void store_ptr(T *location, T value);

template <>
void store_ptr<char>(char *location, char value) {
  __asm__ __volatile__(
      "strb %1, [%0]\n\t"
      : "+r" (location)
      : "r" (value)
      : "memory"
  );
}


template <>
void store_ptr<short>(short *location, short value) {
  __asm__ __volatile__(
      "strh %1, [%0]\n\t"
      : "+r" (location)
      : "r" (value)
      : "memory"
  );
}
Run Code Online (Sandbox Code Playgroud)

如果模板可以根据模板类型对指令附录(“b”、“h”...)进行字符串化,那就太好了。

template <typename T>
void store_ptr<T>(T *location, T value) {
  __asm__ __volatile__(
     "str" stringify_template_type(T) " %1, [%0]\n\t"
     : "+r" (location)
     : "r" …
Run Code Online (Sandbox Code Playgroud)

c++ templates inline-assembly c++11

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

删除复制构造函数时,为什么重载决议不会返回到参考基类的构造函数?

作为这个问题的后续问题

class Base {
    public:
    virtual ~Base() {}
    virtual void func() = 0;
};

class A : public Base {
    public:
     void func() override { std::cout << this << std::endl; }
};

class B : public Base {
    private:
     Base& base;

     public:
      B(B&) = delete;
      B(Base& b) : base(b) {}
      void func() override { std::cout << &base << std::endl; }
};

int main()
{
  A a;
  B b(a);
  B c(b);

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

B(Base& b)删除复制构造函数时,为什么重载决议不会回退到引用基类 …

c++ language-lawyer

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

用'this'指针初始化std :: array

我试图初始化模板类this中的数组,并将指针传递给数组中的所有元素.这是我的类可能是这样的:

template<int NUM> class outer_class;

template<int N>
class inner_class {
  private:
   outer_class<N> *cl;
  public:
   inner_class(outer_class<N> *num) {
    cl = num;
   }
   void print_num() {
    cl->print_num();
   }

};

template<int NUM> class outer_class {
 private:
  int number = NUM;

  // --> here I basically want NUM times 'this' <-- 
  std::array<inner_class<NUM>, NUM> cl = { this, this, this, this }; 

 public:

  void print_num() {
    std::cout << number << std::endl;
  }

  void print() {
    cl[NUM - 1].print_num();
  }
};

int main() { …
Run Code Online (Sandbox Code Playgroud)

c++ arrays this c++11

3
推荐指数
1
解决办法
389
查看次数

将成员函数指针作为模板参数传递

我想创建一个包装类,它可以在模板的帮助下调用包装类的成员函数(任何类型).这是我到目前为止:

template <typename T>
class wrapper {
  public:    
    template<typename R, R (T::*func)()>
    void call_func() {
      (wrapped.*func)();
    }

  private:
    T wrapped;  
};

class some_class {
  private:
    int i = 2;
  public:
    void some_func() {
      std::cout << i << std::endl;
    }
};

int main() {
    wrapper<some_class> wr;
    // How I need to call at the moment:
    wr.call_func<void, &some_class::some_func>();
    // How I want call:
    wr.call_func<&some_class::some_func>();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

正如您在main函数的注释中所看到的,我想调用包装函数而不显式指定包装成员函数的返回类型.(如何)可以在C++ 11中完成?

c++ templates c++11

3
推荐指数
1
解决办法
1436
查看次数

自定义规则不会构建依赖目标

我想在qemu上运行单元测试.我创建了一个自定义规则,它使用规则中指定的参数调用qemu.其中一个参数是elf文件(规则属性"t​​arget"),qemu将其用作内核.
当我使用以下命令调用我的自定义规则时,elf文件("kernel.elf")不会被编译:

 bazel build //test:custom_rule
Run Code Online (Sandbox Code Playgroud)

即使bazel query 'deps(//test:custom_rule)'将目标":kernel.elf"列为依赖项,也会发生这种情况.

此外,我有自定义规则的另一个问题.当我手动构建":kernel.elf"并调用自定义规则后,qemu告诉我,它无法加载内核文件.在shell中手动调用qemu命令确实有效,所以我猜问题不在于"kernel.elf"文件中.

有人对我的问题有答案吗?

提前致谢!

run_tests.bzl

def _impl(ctx):
  qemu = ctx.attr.qemu
  machine = ctx.attr.machine
  cpu = ctx.attr.cpu
  target = ctx.file.target.path
  output = ctx.outputs.out
  # The command may only access files declared in inputs.
  ctx.actions.run_shell(
      arguments = [qemu, machine, cpu, target],
      outputs=[output],
      command="$1 -M $2 -cpu $3 -nographic -monitor null 
               -serial null -semihosting -kernel $4 > %s" % (output.path))


run_tests = rule(
    implementation=_impl,
    attrs = {"qemu" : attr.string(),
             "machine" : attr.string(),
             "cpu" : …
Run Code Online (Sandbox Code Playgroud)

bazel

2
推荐指数
1
解决办法
510
查看次数

为什么 operator new[] 为数组的大小分配内存?

我正在实现一个堆栈分配器并重载operator new[]某个类以使用我自己的分配器。然后我注意到operator new[]为分配的数组中的元素数量分配了内存。
例如:

test_class* test_arr = new test_class[5];

从我的分配器请求 8 个字节 + 5*sizeof(test_class) 并且在前 8 个字节中它存储数组的大小,在这种情况下为 5。

为什么这样做?跟踪分配的内存量是我的分配器的工作。对于那部分,它真的没有意义,是吗?那么有什么意义呢?另外,我可以(还是不应该?)我以某种方式“关闭它”?

c++ dynamic-memory-allocation

2
推荐指数
1
解决办法
570
查看次数