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

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

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

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

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

这是抛出问题的代码片段:

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* 类型,因为它需要一个地址 (或者至少我正在使用的示例是使用它).

有趣的是,我认为 & 运算符返回 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 从未真正创建。

Funny thing is, I thought that the & operator returned an unsigned int*, as returning an int* doesn't make sense, seeing as computers don't have negative addresses in their memory

这不是内存地址号(指针的基础值)的符号性,它是存储在内存地址中的数据类型的符号性,在本例中是整数。

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

as returning an int* doesn't make sense, seeing as computers don't have negative addresses in their memory.

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

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

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

Funny thing is, I thought that the & operator returned an unsigned int*, as returning an int* doesn't make sense, seeing as computers don't have negative addresses in their memory.

那不是 "funny";这是错误的。

应用于 T 类型对象的寻址运算符为您提供了 T*.

类型的指针

期间。

T 是无符号类型还是有符号类型不在其中,并且与有关计算机是否可能具有负地址的哲学辩论无关。事实上,指针 通常是 有符号的,因为如果没有,当您试图计算两个地址之间的差异或在地址中向后走时,您很快就会卡住 space.

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