V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
smdbh
V2EX  ›  程序员

C 下两个关于长度的问题

  •  
  •   smdbh · 2018-12-15 14:20:13 +08:00 · 1994 次点击
    这是一个创建于 1930 天前的主题,其中的信息可能已经有所发展或是发生改变。

    问题

    1. pfn_test 类型的 pfn, 长度使用++运算,为什么每次只加 1 ?
    2. func1,func2 加入到 section 中后,间隔变为 27 字节, 这个依据是什么,试了几个平台,这个值也不固定,如果要遍历 section 中的函数,这个 pfn++要如何写?

    $cat main.c

    #include <stdint.h>
    #include <stdio.h>
    
    typedef int (*pfn_test)(void);
    #define UTEST      __attribute__(( unused, section("mysection")))
    
    int UTEST func1(void)
    {
        printf("func is %s\n", __func__);
    }
    
    static int UTEST func2(void)
    {
        printf("func is %s\n", __func__);
    }
    
    extern pfn_test __start_mysection;
    extern pfn_test __stop_mysection;
    
    int main(int argc, char *argv[])
    {
        printf("start sec %p\n", &__start_mysection);
        printf("stop sec %p\n", &__stop_mysection);
    
        printf("func1 %p\n", func1);
        printf("func2 %p, %lu\n", func2, func2 - func1);
    
    
        pfn_test pfn = &__start_mysection;
    
        printf("size %lu\n", sizeof(pfn));
        for (int i = 0; i <3; ++i) {
            printf("addr %p\n", pfn++);
    
        }
    
        pfn = &__start_mysection;
        for (int i = 0; i <2; ++i) {
            pfn();
            pfn += 27;
    
        }
    
        printf("done");
    }
    

    $ gcc main.c && ./a.out

    start sec 0x4006a2
    stop sec 0x4006d8
    func1 0x4006a2
    func2 0x4006bd, 27
    size 8
    addr 0x4006a2
    addr 0x4006a3
    addr 0x4006a4
    func is func1
    func is func2
    
    第 1 条附言  ·  2018-12-15 21:23:53 +08:00
    1. 谢谢 1 楼的帮助,先通过结构体包裹固定大小。
    3 条回复    2018-12-15 15:48:57 +08:00
    Jex
        1
    Jex  
       2018-12-15 14:50:34 +08:00   ❤️ 3
    C 语言并不支持函数指针运算,GCC -Wpointer-arith 有警告。
    bilosikia
        2
    bilosikia  
       2018-12-15 15:15:54 +08:00   ❤️ 1
    改成这样
    printf("size %lu\n", sizeof(*pfn));

    start sec 0x7fcf6ac007e2
    stop sec 0x7fcf6ac00820
    func1 0x7fcf6ac007e2
    func2 0x7fcf6ac00801, 31
    size 1
    addr 0x7fcf6ac007e2
    addr 0x7fcf6ac007e3
    addr 0x7fcf6ac007e4
    func is func1
    Segmentation fault (core dumped)

    对指针的加法运算是有指针指向的类型决定的,pfn ( pfn_test pfn = &__start_mysection; 这已经类型不匹配了)是指向的一个函数类型,sizeof(函数类型)= 1,
    所以++ 只加了一

    另外 c++是禁止对函数指针做加减法运算的
    为什么 sizeof (函数类型)为一呢?
    sizeof cannot be used with function types, incomplete types, or bit-field glvalues.
    Jex
        3
    Jex  
       2018-12-15 15:48:57 +08:00   ❤️ 2
    直接定义一个函数数组放到 section 里面,遍历这个数组就行了。你那两个函数指针之间的间隔就是其中一个函数代码体的大小。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   4091 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 05:20 · PVG 13:20 · LAX 22:20 · JFK 01:20
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.