小编Lil*_*lás的帖子

可以在C代码中将链接器脚本符号地址作为编译时常量值吗?

我想得到我的程序结束的地址,并在编译/链接器时检查我是否有足够的空间,在代码之后,在执行时间放置一些随机数据.

但是由于PROVIDE关键字提供的符号与C代码中的常规变量一样,我无法在编译时验证它.

在链接器脚本中我有符号:

PROVIDE (__data_end_rom   = _etext + SIZEOF (.data));
Run Code Online (Sandbox Code Playgroud)

所以我可以用这个符号来获取代码结尾的地址:

extern u16 __data_end_rom;
Run Code Online (Sandbox Code Playgroud)

如果我认为结束地址是0xffff,我可以计算可用内存:

#define AVAILABLE_MEM (0Xffff - &__data_end_rom)
Run Code Online (Sandbox Code Playgroud)

我正在考虑使用gcc 4.6中提供的_Static_assert(cond,message)检查可用内存

_Static_assert(SIZE_I_WANT_TO_ASSURE <= AVAILABLE_MEM, "NOT ENOUGH MEMORY!!!");
Run Code Online (Sandbox Code Playgroud)

我的问题是:宏AVAILABLE_MEM不是在编译时计算的,所以我收到错误:

error: expression in static assertion is not constant
Run Code Online (Sandbox Code Playgroud)

有没有办法直接在标签中或以其他方式提供__data_end_rom地址?

我知道我无法在编译时得到它,因为符号只会在链接器时间内链接,所以有一些方法可以使链接器失败?

我可以直接在链接器脚本中检查这个,但我不喜欢这样做,因为SIZE_I_WANT_TO_ASSURE是从配置头中的其他宏计算的另一个宏.

c embedded gcc bare-metal linker-scripts

7
推荐指数
2
解决办法
8163
查看次数

C - 对于非指针函数的参数,const的用户有哪些优势?

我想知道在调用函数时用户是否有任何优势

A)void func(int i);

或类似的功能

B)void func(const int i);

在func内部,参数i无论如何都将被复制到堆栈(或编译器在其优化中选择的位置),对于调用此函数的用户,A和B之间没有区别.

所以如果一个工具类似于:

A)

void func(int i)
{
    i = another_func(i);
    printf("%d", i);
}
Run Code Online (Sandbox Code Playgroud)

或者使用const

B)

void func(const int i)
{
    int j = another_func(i);
    printf("%d", j);
}
Run Code Online (Sandbox Code Playgroud)

我的问题 :

实施B有什么优势?编译器可以执行任何类型的优化?A和B只是一个简单的例子,这些问题对其他情况有效.

我理解在指针中使用const的优点(例如const void*data),因为我们告诉用户我们不会修改它的内容,但我不理解const的用法,除了警告函数的程序员他不应该修改它,但在我看来,在API头文件中使用const是没用的.

谢谢你的帮助.

c const

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

C/cmake - 在TARGET_LINK_LIBRARIES中指定库时,如何向(未使用的)库添加链接器标志?

在我的项目的根目录中,我有一个子目录my_lib和另一个子目录my_app.该库my_lib定义了填充链接器定义的节的表,这些表不是直接使用的my_app,因此该库未链接.

为了强制my_lib被链接,我添加了标志--whole-archive,如下所述.

它的工作原理!

在根目录的CMakelist.txt中,我有以下内容:

SET(CMAKE_EXE_LINKER_FLAGS "-mmcu=cc430f6137 -Wl,--gc-sections -Wl,--whole-archive -lMY_LIB -Wl,--no-whole-archive")
ADD_SUBDIRECTORY(my_lib)
Run Code Online (Sandbox Code Playgroud)

CMakelist.txtmy_lib,我有:

ADD_LIBRARY(MY_LIB
    my_lib.c
)
TARGET_LINK_LIBRARIES(MY_LIB)
Run Code Online (Sandbox Code Playgroud)

CMakelist.txtmy_app,我有:

ADD_EXECUTABLE(my_app my_app.c)
TARGET_LINK_LIBRARIES(my_app MY_LIB)
Run Code Online (Sandbox Code Playgroud)

我的问题是我只想使用这个标志(--whole-archive)如果MY_LIBTARGET_LINK_LIBRARIESin CMakelist.txt中指定my_app.

如果最后一行TARGET_LINK_LIBRARIES(my_app MY_LIB)是不存在的,我不希望添加"-Wl,--whole-archive -lMY_LIB -Wl,--no-whole-archive"CMAKE_EXE_LINKER_FLAGS.

我试图从root中的CMakelist.txt中删除此标志,并将以下内容添加到CMakelist.txtin my_lib子目录中:

SET_TARGET_PROPERTIES(MY_LIB PROPERTIES CMAKE_EXE_LINKER_FLAGS "-Wl,--whole-archive -lMY_LIB -Wl,--no-whole-archive")
Run Code Online (Sandbox Code Playgroud)

但这不起作用.

我怎样才能做到这一点?

c linker cmake

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

C++:两个指针(据说是)到同一个地址.更改其中一个的内容不会更改另一个的内容

我是C++和arduino的新手,我不了解发生了什么.

问题是 :

我有以下变量:

char *_array;
char _data[2];
Run Code Online (Sandbox Code Playgroud)

当我这样做:_array = data;然后我改变_data的内容,比如data[0] = 'C',data[1] = 'D'._array的内容不会改变,我需要_array = _data再次执行更改.

似乎他们没有指向同一个地址.

下面的代码就是这个例子,我的第三个印刷品应该是"3CD"代替"3AB",但事实并非如此.

请问你能帮帮我吗?我不明白.谢谢!

#include <SoftwareSerial.h>
class Base {
    public:
        Base() {;};
        void setArray(char* array) {_array = array;}
        char *getArray() {return _array;}
    private:
        char *_array;
};

class A : public Base{
    public:
        A() : Base() {;};
        A(char data1, char data2)
        : Base()
        {
            setData(data1, data2);
            setArray(_data);
        }
        void setData(char data1, char data2) …
Run Code Online (Sandbox Code Playgroud)

c++ pointers arduino

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

冒号是什么意思:x86汇编GAS语法在%ds :(%bx)中是什么意思?

我是x86程序集的新手,我正在尝试理解本文档中的代码:http://www.cs.cmu.edu/~410-s07/p4/p4-boot.pdf第3页:

movw $0x1234, %ax
movw %ax, %ds
movw $0x5678, %bx
# The following instruction is the same as "movw $0x1337, (%bx)".
movw $0x1337, %ds:(%bx) # Places 0x1337 into memory word 0x179b8.
# Segment Base: %ds << 4: 12340
# Offset: %bx: + 5678
# -------
# Linear Address: 179b8
Run Code Online (Sandbox Code Playgroud)

但我不理解这个命令:

movw $0x1337, %ds:(%bx) # Places 0x1337 into memory word 0x179b8.
Run Code Online (Sandbox Code Playgroud)

为什么将%ds与(%bx)连接与((%ds << 4)|%bx)相同?

由于我处于实模式(16位),串联不应该是%ds << 8?而不是%ds << 4

为什么括号只是%bx左右?而不是整个结构,如:movw $ 0x1337,(%ds:%bx)?

syntax x86 assembly real-mode gnu-assembler

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

如何从多行文件中提取子字符串

我正在尝试从 /etc/os-release 中提取操作系统名称,其中包含:

...
NAME="Os Name"
...
Run Code Online (Sandbox Code Playgroud)

但是当我执行时:

sed 's/.*NAME="\([^"]*\).*/\1/' /etc/os-release
Run Code Online (Sandbox Code Playgroud)

它正确捕获了操作系统名称,但它打印了所有其他行,而不是仅打印捕获的字符串,为什么?

os-release 文件的内容

cat /etc/os-release 
NAME="CentOS Linux"
VERSION="7 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
PRETTY_NAME="CentOS Linux 7 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:7"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"

CENTOS_MANTISBT_PROJECT="CentOS-7"
CENTOS_MANTISBT_PROJECT_VERSION="7"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="7"
Run Code Online (Sandbox Code Playgroud)

应该只输出“CentOS Linux”但它输出所有行的 sed 命令:

$ sed 's/.*NAME="\([^"]*\).*/\1/' /etc/os-release
CentOS Linux
VERSION="7 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
CentOS Linux 7 (Core)
ANSI_COLOR="0;31"
cpe:/o:centos:centos:7
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"

CENTOS_MANTISBT_PROJECT="CentOS-7"
CENTOS_MANTISBT_PROJECT_VERSION="7"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="7"
Run Code Online (Sandbox Code Playgroud)

regex bash sed

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

ext2 / ext3 / ext4文件系统有正式规范吗?

我想知道,对于蓝牙,我们有由蓝牙特殊利益集团管理的IEEE 802.15.1标准。对于Wifi,我们拥有IEEE 802.11标准以及Wifi联盟。对于PCIe上的NVMe SSD,我们有nvmexpress来规范和发布其官方文档。

因此,通常会有一个监管机构来决定事情并标准化一些事情,以允许几种不同实现之间的互操作性。

但是对于ext2 / ext3 / ext4文件系统,除了Linux内核代码之外,我没有找到任何官方标准。

这些文件系统基本上是由内核社区决定的吗?他们是否承诺不更改它们,使其仍然与其他操作系统兼容?

还是在某处有一些官方规范?谁提供的?

谢谢

filesystems ext2 ext3 ext4

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

pkcs11-tool:为什么我需要指定要加载的模块?

当我运行 pkcs11-tool 时,我总是需要指定一个模块:

pkcs11-tool --module=/usr/lib/x86_64-linux-gnu/opensc-pkcs11.so -L
Run Code Online (Sandbox Code Playgroud)

该模块的用途是什么以及 pkcs11-tool 如何使用它?我还可以使用哪些其他可能的模块?它们之间有什么区别?

我尝试使用另一个(“/usr/lib/x86_64-linux-gnu/nss/libnssckbi.so”),但我总是得到一个空插槽,所以我认为模块的用途有所不同?

pkcs#11

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

bash:在代码块或其末尾重定向stdin有什么区别?

在代码块语句中添加重定向而不是在它的末尾添加它有什么区别吗?

例如,有什么区别:

if cat <<< foo; then
    code ...
fi
Run Code Online (Sandbox Code Playgroud)

和:

if cat; then
    code ...
fi <<< foo
Run Code Online (Sandbox Code Playgroud)

提前致谢

bash io-redirection

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