【问题标题】:warning C4047: '=' : 'int' differs in levels of indirection from 'char *'警告 C4047:“=”:“int”与“char *”的间接级别不同
【发布时间】:2026-01-07 23:55:02
【问题描述】:
int utstrlen(char* src){
    int length=0 ;
    if(isOurs(src) ==1){
        length = src - 2 * sizeof(int);
    }
    return length;
}

我收到警告 C4047: '=' : 'int' 在间接级别上与来自行 length = src - 2 * sizeof(int); 的 'char *' 错误的间接级别不同@ 有人可以解释它有什么问题吗?谢谢!

【问题讨论】:

  • 您正在计算该行中的指针,而不是数量或长度。你能提供伪代码或你想要长度的描述吗?

标签: c


【解决方案1】:

根据您的previous question,您想要

length = *((int *)(src - 2 * sizeof(int)));

虽然假设没有填充。更好的方法是使用offsetof():

String *beg = (String *)(src - offsetof(struct String, ptr));
length = beg->length;

我假设您使用的是上一个问题中的结构。

【讨论】:

    【解决方案2】:

    我怀疑你有这样的字符串结构:

    struct string {
        int length;
        int somethingelse; /* thanks alok */
        char *str;
    }
    

    当给定一个指向str的指针时,这个函数试图访问长度字段?我对么?我想这就是 isOurs 检查的内容(以确保它不是任何旧字符串)。在这种情况下,您需要这样:

    length = (*((int*)(src - 2))) * sizeof(int);

    int utstrlen(char* src){
        int length=0 ;
        if(isOurs(src) ==1){
              length = *((int*)(src - (2 * sizeof(int)))); /* from str moveback 2 ints worth*/
        }
        else {
            //return strlen(src) ?
        }
        return length;
    }
    

    但理想情况下你会这样做。它不是可移植的或可维护的。如果编译器插入你不知道的填充会发生什么? C99 标准说它不会在 0 大小的数组和前一个字段之间放置填充,但没有什么可以阻止它与其他字段一起发疯(例如,如果您有混合类型)。

    如果有人稍后出现并在结构中插入更多数据会发生什么?自然,他们必须将它放在字段 str 之前,因为“struct hack”的工作原理是将它放在最后。理想情况下,您应该使用 offsetof() 来执行此操作,这是一个标准宏。 Alok 在这里提供了一个更好的解决方案 Ugly Macro Interpretation (just 1 line)

    编辑(似乎在我输入新的最后一段的 2 分钟内,Alok 的 offsetof() 答案已被接受;))

    【讨论】:

    • 看起来也不对。 length = *((int *)src - 2); 似乎更有可能。
    • 我不确定您在length = ... 行中要做什么。很可能他的结构在char * 之前有两个int 成员,减去2*sizeof(int) 会给他一个指向结构开头的地址(假设没有填充)。更好的方法是使用offsetof 宏。
    • 完全。如果他说“这就是我正在做的事情”,我只会说“改用 offsetof()”。我假设他想从 str 返回 2 个字节,这会将他指向长度的开始(如果它是 2 个字节长......:/)。你的 2 整数理论听起来更有可能。
    • 查看*.com/questions/2038910/… 了解他的结构定义。
    • 我看到你已经用 offsetof() 回答了他。现在不需要我的数百万个括号了:)
    【解决方案3】:

    src - 2 * sizeof(int) 是指针算术 - 该表达式的结果是另一个 char* 指针。您正在尝试将char* 分配给length,这是一个int,这就是您收到错误的原因。我不知道这个函数应该做什么,但如果你真的想要你可以将值转换为int:length = (int)(src - 2 * sizeof(int))。但同样,我看不到您的功能中的用途。

    【讨论】:

      【解决方案4】:

      src 是一个char *;长度是int。因此,编译器将此行视为类似于:

      length = (int) (src - 2 * sizeof(int));
      

      我不确定你对警告有什么困惑,我也对你的代码试图做什么感到困惑。那么,我的建议是尝试以下测试代码,看看它会打印什么:

      void test(void) {
          char *foo = "hello\n";
      
          printf("%s\n", foo);
          printf("%d\n", (int) foo);
          printf("%s\n", foo+1);
          printf("%d\n", ((int) foo) + 1);
      }
      

      您会注意到算术在指针的一种用法中比在另一种用法中更有意义。

      【讨论】:

        【解决方案5】:

        当然。

        src 是一个指针; 2 * sizeof(int) 是一个整数值。

        虽然确实是合法的

        1. 将两个指针相减(结果是它们的地址不同,为 integer 整数类型,可能是 size_tptrdiff_t ),还有

        2. 从指针中减去一个整数(结果是指向该指针前一点位置的指针),

        尝试将 (2) 的结果分配给整数变量 (length) 是不合法的。

        【讨论】:

        • 没错,它是一个整数类型,但不是类型int。但是,根据编译器的不同,它可以与 int 相互分配。
        • 它的类型是ptrdiff_t,虽然严格来说只能减去两个指向数组成员的指针。
        最近更新 更多