编译器错误:从int*到无符号int*的转换无效[-fpermission]

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

本文关键字:int 转换 无效 -fpermission 错误 编译器 无符号      更新时间:2023-10-16

我今天遇到了最奇怪的问题。我在网上做了一个例子,令我毫不惊讶的是,它不起作用(他们几乎从不起作用)。我自己去修复它,但我似乎被这个错误卡住了:

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 Messagen";
    char msg2[] = "Hello Worldn";
    // Validate Argument Count
    if(argc != 2)
    {
        printf("Usage: %s digestnamen", 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 %sn", 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实际上从未被创建。

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

这并不"好笑";这是错误的。

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

期间。

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

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

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

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

CCD_ 15是指向CCD_。unsigned不引用指针值。

因此,解决方案是将int更改为无符号int。

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

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

根据规范将您的md_length更改为unsigned int,它应该是可以的。