小编nic*_*pro的帖子

C/C++标题和实现文件:它们如何工作?

可能是一个愚蠢的问题,但我现在在网上和网上搜索了很长一段时间并且无法得出一个明确的答案(我的尽职调查谷歌搜索).

所以我是编程的新手......我的问题是,主函数如何知道不同文件中的函数定义(实现)?

恩.说我有3个文件

  • main.cpp中
  • myfunction.cpp
  • myfunction.hpp

//main.cpp

#include "myfunction.hpp"
int main() {
  int A = myfunction( 12 );
  ...
}
Run Code Online (Sandbox Code Playgroud)

-

//myfunction.cpp

#include "myfunction.hpp"
int myfunction( int x ) {
  return x * x;
}
Run Code Online (Sandbox Code Playgroud)

-

//myfunction.hpp

int myfunction( int x );
Run Code Online (Sandbox Code Playgroud)

-

我得到预处理器如何包含头代码,但是头和主函数如何知道函数定义是否存在,更不用说它了?

如果不清楚或者我对这里的新事物有很大误解,我会道歉

c++ compilation header-files

40
推荐指数
3
解决办法
2万
查看次数

无法将非类型模板参数传递给基类模板

现代 C++ 新手,试图弄清楚这里发生了什么。以下代码编译正常:

template<int base_num>
class Base{
public:
  Base() {}
};


template<int derived_num>
class Derived : public Base<0> { // Integer literal passed to base template
public:
  Derived(): Base() {}
};
Run Code Online (Sandbox Code Playgroud)

而以下内容:

template<int base_num>
class Base{
public:
  Base() {}
};


template<int derived_num>
class Derived : public Base<derived_num> { // Non-type template parameter passed to base template
public:
  Derived(): Base() {}
};
Run Code Online (Sandbox Code Playgroud)

失败:

类 'Derived<derived_num>' 没有任何名为 'Base' 的字段

我推测发生这种情况是因为derived_num它本身不算作“结构类型”,但不确定。希望有人可以解释这里发生了什么,以及是否有办法将非类型模板参数“传递”到基类模板。

更新:

显式定义模板“修复”了这个

template<int derived_num>
class Derived : public Base<derived_num> { …
Run Code Online (Sandbox Code Playgroud)

c++ templates

7
推荐指数
0
解决办法
61
查看次数

C++20 中的用户定义推导指南

我正在std::variant使用“重载”模式std::visit,如下所示:

#include <iostream>
#include <variant>

template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;

int main(void) {
  std::variant<int, float> var;
  auto fs = overloaded {
    [](int var) {std::cout << "var is int" << std::endl;},
    [](float var) {std::cout << "var is float" << std::endl;}
  };
  var = 0;
  std::visit(fs, var);
  var = 0.0f;
  std::visit(fs, var);
}
Run Code Online (Sandbox Code Playgroud)

在 cppreference 上,有一个示例

// explicit deduction guide (not needed as of C++20) …
Run Code Online (Sandbox Code Playgroud)

c++ language-lawyer type-deduction c++20

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

gcc 8.2+ 在 x86 上调用之前并不总是对齐堆栈?

当前 (Linux) 版本的 SysV i386 ABI 需要在调用之前进行 16 字节堆栈对齐:

输入参数区域的末尾应在 16(32,如果 __m256 在堆栈上传递)字节边界上对齐。换句话说,当控制权转移到函数入口点时,值 (%esp + 4) 始终是 16 (32) 的倍数。

在 GCC 8.1 上,此代码在调用之前将堆栈与 16 字节边界对齐callee:( Godbolt )

来源 # 字节
称呼 4
推送ebp 4
子特别是,24 24
子特别, 4 4
推入eax 4
推入eax 4
推入eax 4
全部的 48

在 GCC 8.2 及更高版本的所有版本上,它与 4 字节边界对齐:( Godbolt )

来源 # 字节
称呼 4
推送ebp 4
子特别,16 16
推入eax 4
推入eax 4
推入eax 4
全部的 36

如果我们缩短增加所需的参数数量,则很容易验证 …

c linux x86 gcc abi

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

如何使用 Cmake 用 NASM 构建二进制文件

我正在学习 x64 并且我讨厌 make,所以我试图让 cmake 使用 NASM 构建二进制文件。

cmake 大致支持这一点,但文档很垃圾。这就是我现在所做的工作,将堆栈溢出中的内容拼凑在一起,然后删除不会破坏构建的所有内容:

cmake_minimum_required(VERSION 3.14)

set(CMAKE_ASM_NASM_LINK_EXECUTABLE "ld <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
set(CMAKE_ASM_NASM_OBJECT_FORMAT elf64)

project(test_project ASM_NASM)

set_source_files_properties(test.s PROPERTIES LANGUAGE ASM_NASM)
add_executable(test test.s)
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
    target_compile_options(test PRIVATE -g -Fdwarf)
endif()
Run Code Online (Sandbox Code Playgroud)

所以有几个问题,为什么我必须告诉 cmake 使用ld链接,有没有更好的方法来做到这一点?

有什么target_object_format可以用来指定对象格式而不是全局设置的内容吗?

有没有办法让 cmake 识别新的扩展名,而不是专门告诉它每个文件是 ASM_NASM?

assembly cmake nasm

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