You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何替换const char*为std::string并解决重定义编译错误?

问题:err函数重载与重定义错误修复

初始可编译的const char*版本代码

最初的err函数采用const char*参数,可正常编译:

static LISP err(const char* message, LISP x, const char* s)
{
    nointerrupt = 1;
    if NNULLP(x)
    {
        fprintf(stderr, "SIOD ERROR: %s %s: ",
            (message) ? message : "?",
            (s) ? s : ""
        );
        lprin1f(x, stderr);
        fprintf(stderr, "\n");
        fflush(stderr);
    }
    else
    {
        fprintf(stderr, "SIOD ERROR: %s %s\n",
            (message) ? message : "?",
            (s) ? s : ""
        );
        fflush(stderr);
    }

    if (show_backtrace == 1)
        display_backtrace(NIL);

    if (errjmp_ok == 1) { setvar(sym_errobj, x, NIL); longjmp(*est_errjmp, 1); }
    close_open_files();  /* can give clue to where error is */
    fprintf(stderr, "%s: fatal error exiting.\n", siod_prog_name);
    if (fatal_exit_hook)
        (*fatal_exit_hook)();
    else
        exit(1);
    return(NIL);
}

LISP err(const char* message, LISP x)
{
    return err(message, x, NULL);
}

LISP err(const char* message, const char* x)
{
    return err(message, NULL, x);
}

修改重载函数时的编译错误

尝试拼接字符串修改重载函数后,编译失败:

LISP err(const char* message, const char* x)
{
    std::string full_message = "fromchar_" + std::string(message);
    return err(full_message.c_str(), NULL, x);
}
LISP err(const char* message, LISP x)
{
    const char* func_name = "fromlisp_";
    // 错误:const char*无法直接与std::string相加,结果是std::string,不能赋值给const char*
    const char* final_message = (message) ? (func_name + std::string(message)) : "?";
    return err(final_message.c_str(), x, NULL);
}

编译错误提示:final_message并非const char*类型

改用std::string后的重定义错误

将参数全部替换为std::string后,出现重定义错误:

static LISP err(const std::string& message, LISP x, const std::string& s)
{
    nointerrupt = 1;
    if (NNULLP(x))
    {
        fprintf(stderr, "SIOD nullpointer error. Wir wissen aber den typ nicht: %s %s: ", message.c_str(), s.c_str());
        lprin1f(x, stderr);
        fprintf(stderr, "\n");
        fflush(stderr);
    }
    else
    {
        fprintf(stderr, "SIOD anderer error: %s %s\n", message.c_str(), s.c_str());
        fflush(stderr);
    }

    if (show_backtrace == 1)
        display_backtrace(NIL);

    if (errjmp_ok == 1) { setvar(sym_errobj, x, NIL); longjmp(*est_errjmp, 1); }
    close_open_files();  /* can give clue to where error is */
    fprintf(stderr, "%s: fatal error exiting.\n", siod_prog_name);
    if (fatal_exit_hook)
        (*fatal_exit_hook)();
    else
        exit(1);
    return(NIL);
}
LISP err(const std::string& message, LISP x)
{
    return err("error type A:" + message, x, std::string());
}

LISP err(const std::string& message, const std::string& x)
{
    return err("error type B:" + message, LISP(), x);
}
// 错误:该函数与静态三参数err函数签名完全一致,导致重定义
LISP err(const std::string& message, LISP x, const std::string& x_str)
{
    const std::string func_name = "error from lisp_";
    const std::string final_message = (message.empty()) ? "?" : func_name + message;
    return err(final_message, x, x_str);
}

编译错误提示:

slib.cc:733:6: error: redefinition of ‘obj* err(const string&, LISP, const string&)’
  733 | LISP err(const std::string& message, LISP x, const std::string& x_str)
      |      ^~~
slib.cc:696:13: note: ‘obj* err(const string&, LISP, const string&)’ previously defined here
  696 | static LISP err(const std::string& message, LISP x, const std::string& s)
      |             ^~

修复方案

方案一:修复std::string版本的重定义问题

重定义错误的核心原因是:最后添加的三参数err函数,与静态的三参数err函数签名完全一致(仅参数名不同,C++中参数名不影响函数签名),因此被视为同一个函数,导致重复定义。

修复步骤:

  1. 删除重复的三参数重载函数LISP err(const std::string& message, LISP x, const std::string& x_str)。
  2. 如果需要给消息添加前缀逻辑,直接在对应的双参数重载函数中实现,调用静态三参数函数即可。

修复后的代码示例:

static LISP err(const std::string& message, LISP x, const std::string& s)
{
    nointerrupt = 1;
    if (NNULLP(x))
    {
        fprintf(stderr, "SIOD ERROR: %s %s: ", 
            message.empty() ? "?" : message.c_str(), 
            s.empty() ? "" : s.c_str()
        );
        lprin1f(x, stderr);
        fprintf(stderr, "\n");
        fflush(stderr);
    }
    else
    {
        fprintf(stderr, "SIOD ERROR: %s %s\n", 
            message.empty() ? "?" : message.c_str(), 
            s.empty() ? "" : s.c_str()
        );
        fflush(stderr);
    }

    if (show_backtrace == 1)
        display_backtrace(NIL);

    if (errjmp_ok == 1) { setvar(sym_errobj, x, NIL); longjmp(*est_errjmp, 1); }
    close_open_files();
    fprintf(stderr, "%s: fatal error exiting.\n", siod_prog_name);
    if (fatal_exit_hook)
        (*fatal_exit_hook)();
    else
        exit(1);
    return(NIL);
}

LISP err(const std::string& message, LISP x)
{
    std::string final_msg = "fromlisp_" + message;
    return err(final_msg, x, std::string());
}

LISP err(const std::string& message, const std::string& x)
{
    std::string final_msg = "fromchar_" + message;
    return err(final_msg, LISP(), x);
}

方案二:修复原始const char*版本的拼接错误

如果不想切换到std::string,只需修正字符串拼接的错误:const char*不能直接与std::string相加,需要先将const char*转为std::string再拼接,最后用c_str()获取const char*指针。

修复后的代码示例:

static LISP err(const char* message, LISP x, const char* s)
{
    // 保留原实现不变
    nointerrupt = 1;
    if NNULLP(x)
    {
        fprintf(stderr, "SIOD ERROR: %s %s: ",
            (message) ? message : "?",
            (s) ? s : ""
        );
        lprin1f(x, stderr);
        fprintf(stderr, "\n");
        fflush(stderr);
    }
    else
    {
        fprintf(stderr, "SIOD ERROR: %s %s\n",
            (message) ? message : "?",
            (s) ? s : ""
        );
        fflush(stderr);
    }

    if (show_backtrace == 1)
        display_backtrace(NIL);

    if (errjmp_ok == 1) { setvar(sym_errobj, x, NIL); longjmp(*est_errjmp, 1); }
    close_open_files();
    fprintf(stderr, "%s: fatal error exiting.\n", siod_prog_name);
    if (fatal_exit_hook)
        (*fatal_exit_hook)();
    else
        exit(1);
    return(NIL);
}

LISP err(const char* message, LISP x)
{
    std::string final_msg;
    if (message)
        final_msg = std::string("fromlisp_") + message;
    else
        final_msg = "?";
    return err(final_msg.c_str(), x, NULL);
}

LISP err(const char* message, const char* x)
{
    std::string final_msg;
    if (message)
        final_msg = std::string("fromchar_") + message;
    else
        final_msg = "?";
    return err(final_msg.c_str(), NULL, x);
}

内容的提问来源于stack exchange,提问作者tmighty

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 06:30:09