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

C++ 编译器错误:从int*到无符号int*[-fppermissive]的转换无效,c++,pointers,compiler-errors,integer,unsigned-integer,C++,Pointers,Compiler Errors,Integer,Unsigned Integer,我今天遇到了最奇怪的问题。我在网上用了一个例子,但令我惊讶的是,它没有起作用(他们几乎从来没有起过作用)。我自己动手修好了,但我似乎被这个错误卡住了: Error: Invalid Conversion from int* to unsigned int* [-fpermissive] 我明白这一点。我提供了一个int*,它需要一个无符号int*。但是,我不知道为什么会生成int* 下面是引发问题的代码片段: unsigned char md_value[EVP_MAX_MD_SIZE]; i

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

Error: Invalid Conversion from int* to unsigned int* [-fpermissive]
我明白这一点。我提供了一个
int*
,它需要一个
无符号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*
类型,这是因为它需要一个地址(或者至少我正在处理的示例是如何使用它的)

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

如果您想看一看,下面是我下面的示例:

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

源代码:

//* 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;
}
基本上,它抱怨所有的OpenSSL函数

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

gcc example.cpp -o example.out
由于存在错误,
示例.out
实际上从未创建过

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

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

根据规范将您的
md_长度
更改为
无符号整数
,应该可以

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

您误解了类型名称的含义

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

因此,解决方案是将int改为unsigned int

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

这并不“有趣”;这是错误的

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

句号

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


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

运算符的地址返回一个指向其应用的变量类型的指针。如果你在
int
变量上使用
&
,你会得到
int*
,如果你在
float
变量上使用它,你会得到
float*
,如果你在
std::string
对象上使用它,那么你会得到
std::string*
。该死的指针又来烦我了,抓到我了。这看起来是朝着正确的方向迈出的一步,但现在我又遇到了那些奇怪的(.text)错误。@Boom:这是一个无关的问题。就这样吧,很好。我会试着把它整理出来,如果我不能解决它,我会发布一个不同的问题。
gcc example.cpp -o example.out