【问题标题】:Compiler Error: Invalid Conversion from int* to unsigned int* [-fpermissive]编译器错误:从 int* 到 unsigned int* [-fpermissive] 的无效转换
【发布时间】:2015-06-07 16:16:56
【问题描述】:

我今天遇到了最奇怪的问题。我正在使用一个在线示例,但令我惊讶的是,它不起作用(他们几乎从来没有这样做过)。我自己去修复它,但我似乎陷入了这个错误:

Error: Invalid Conversion from int* to unsigned int* [-fpermissive]

我明白这一点。我提供了一个int*,它需要一个unsigned int*。但是,我实际上并不知道为什么会生成int*

这是引发问题的 sn-p 代码:

unsigned char md_value[EVP_MAX_MD_SIZE];
int md_length;

EVP_DigestFinal_ex(md_ctx, md_value, &md_length);

该函数调用的第三个参数&md_length 导致了问题。查看该函数调用的文档 (来自 OpenSSL,如果 很重要),它期望参数是unsigned int* 类型,因为它需要一个地址(或者至少我正在使用的示例是如何使用它的) em>。

有趣的是,我认为 & 运算符返回了 unsigned int*,因为返回 int* 没有意义,因为计算机的内存中没有负地址。

如果您想看一下,这是我正在关注的示例:https://www.openssl.org/docs/crypto/EVP_DigestInit.html

以下是源代码,如果您想自己尝试一下。我怀疑你是否真的需要阅读它来解决这个问题,但是把它放在这里不会有什么坏处。

源代码:

//* Description *//
// Title: Example
// Author: Boom Blockhead
// Example Program to Test OpenSSL

//* Libraries *//
#include <stdio.h>
#include <cstring>
#include <openssl/evp.h>

//* Namespaces *//
using namespace std;

//* Main Method *//
// Runs the Program and Interprets the Command Line
int main(int argc, char* argv[])
{
    // Initialize the Messages
    char msg1[] = "Test Message\n";
    char msg2[] = "Hello World\n";

    // Validate Argument Count
    if(argc != 2)
    {
        printf("Usage: %s digestname\n", argv[0]);
        exit(1);
    }

    // Determine Message Digest by Name
    OpenSSL_add_all_digests();
    const EVP_MD* md = EVP_get_digestbyname(argv[1]);

    // Make sure a Message Digest Type was Found
    if(md == 0)
    {
        printf("Unknown Message Digest %s\n", argv[1]);
        exit(1);
    }

    // Create the Message Digest Context
    EVP_MD_CTX* md_ctx = EVP_MD_CTX_create();

    // Setup the Message Digest Type
    EVP_DigestInit_ex(md_ctx, md, NULL);

    // Add the Messages to be Digested
    EVP_DigestUpdate(md_ctx, msg1, strlen(msg1));
    EVP_DigestUpdate(md_ctx, msg2, strlen(msg2));

    // Digest the Message
    unsigned char md_value[EVP_MAX_MD_SIZE];
    int md_length;

    EVP_DigestFinal_ex(md_ctx, md_value, &md_length); // <--- ERROR

    // Destroy the Message Digest Context
    EVP_MD_CTX_destroy(md_ctx);

    // Print the Digested Text
    printf("Digest is: ");

    for(int i = 0; i < md_length; i++)
        printf("%02x", md_value[i]);

    printf("\n");

    // Clean up the Message Digest
    EVP_cleanup();

    // Exit the Program
    exit(0);
    return 0;
}

此外,将 (unsigned int*) 的显式转换似乎只会让事情变得更糟,因为我会收到以下错误:

example.cpp:(.text+0x91): undefined reference to `OpenSSl_add_all_digests`
...
example.cpp:(.text+0x1ec): undefined reference to `EVP_cleanup`

基本上,它抱怨所有的 OpenSSL 功能。

最后,(同样,这只是为了给你们可能需要的一切)我不会向编译器发送任何有趣的参数。我只是在使用:

gcc example.cpp -o example.out

由于出现错误,example.out 从未真正被创建。

【问题讨论】:

  • address-of 运算符返回一个指向它所应用的变量类型的指针。如果你在int 变量上使用&amp;,你会得到int*,如果你在float 变量上使用它,你会得到float*,如果你在std::string 对象上使用它,你会得到@ 987654343@.

标签: c++ pointers compiler-errors integer unsigned-integer


【解决方案1】:

有趣的是,我认为 & 运算符返回一个 unsigned int*,因为返回一个 int* 没有意义,因为计算机的内存中没有负地址。

这不“好笑”;这是错误的。

应用于T 类型对象的地址运算符会为您提供T* 类型的指针。

期间。

T 是无符号类型还是有符号类型并没有涉及,并且与关于计算机是否可能具有负地址的哲学辩论无关。事实上,指针 通常是有符号的,因为如果没有,当你试图取两个地址之间的差异或在地址空间中倒退时,你很快就会陷入困境。

但这与在您的代码中使用术语 unsigned 无关。

【讨论】:

    【解决方案2】:

    因为返回 int* 没有意义,因为计算机的内存中没有负地址。

    您误解了类型名称的含义。

    unsigned int* 是指向unsigned int 的指针。 unsigned 不引用指针值。

    因此解决方案是将您的 int 更改为 unsigned int。

    【讨论】:

    • 该死的指针又惹我生气了,很好。看起来这是朝着正确方向迈出的一步,但现在我又遇到了那些奇怪的 (.text) 错误。
    • @Boom:这是一个不相关的问题。让我们这样对待它。
    • 很好。我会尝试解决它,如果我无法解决它,请发布一个不同的问题。
    【解决方案3】:

    有趣的是,我认为 & 运算符返回一个 unsigned int*,因为返回一个 int* 没有意义,因为计算机的内存中没有负地址

    这不是内存地址编号(指针的底层值)的有符号性,而是存储在内存地址中的数据类型的有符号性,在本例中为整数。

    根据规范将您的 md_length 更改为 unsigned int 应该没问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-30
      相关资源
      最近更新 更多