3

我想知道 C++ 中是否有一种方法可以将传递给函数的“字符串”(以任何表示形式)假定为该函数的有效字符串。

我对 C/C++ 很陌生,但据我所知,在 C 中,这个问题默认得到回答,因为没有其他方法,你只知道你必须检查:

#include <stdio.h>

void foo(const char *str)
{
    if (str)
        printf("%s\n", str);
}

int main()
{
    char *name = "Jack";
    foo(name);

    return 0;
}

但是由于 C++ 提供了额外的东西,比如引用,我想知道是否可以以一种不需要检查的方式编写 foo()。我试过这样:

#include <iostream>
#include <string>

void foo(const std::string &str)
{
    std::cout << str << std::endl;
}

int main(void)
{
    std::string name = "Jack";
    foo(name);

    std::string *str = NULL;
    foo(*str);

    return 0;
}

但正如你所看到的,我可以欺骗 foo() 来运行 SegFault。所以,我猜你总是要检查,不管怎样?

编辑#1:

好的,首先感谢您的所有回答和未来的回答,他们都非常感谢!

所以总结一下我到目前为止学到的东西:

C++ 中没有语法方法来编写函数定义来消除实际函数调用的误用。

那是对的吗?如果是这样,我认为我的原始问题已得到回答。

因此,现在我尝试将 foo() 编写为尽可能具有防御性,这样无论您如何将 foo() 视为狗,它都不会产生 SegFault。

在 CI 中现在会这样写(假设短路评估):

#include <stdio.h>

void foo(const char *str, const size_t len)
{
    if (str && (str[len - 1] == '\0'))
        printf("%s\n", str);
}

int main()
{
    char *name = "Jack";
    foo(name, 5);

    /* possible mistakes, but foo can handle them */
    foo(name, 4);
    foo(name, -1);
    foo(NULL, 5);

    return 0;
}

在 C++ 中,我正在尝试这个:

#include <iostream>
#include <string>

void foo(const std::string &str)
{
    if (&str)
        std::cout << str << std::endl;
}

int main(void)
{
    std::string name = "Jack";
    foo(name);

    std::string *str = NULL;
    foo(*str);

    return 0;
}

...但我不确定这是否合适,或者在这种情况下,对于例外情况,人们会、可以或应该做什么。

你怎么看?如果您不能防止语法误用,您必须增加预防措施吗?

4

2 回答 2

9
std::string *str = NULL;
foo(*str);

就调用者而言,这是未定义的行为。不是你的问题。所以不,你(的作者foo)不必检查。

即使在 C 语言中,使用指针也不一定要检查。你只需要记录。“参数必须指向一个有效的以 null 结尾的字符串。如果不是,则调用是未定义的行为。” -- 如果用户传递了一个NULL,也就是他们的问题。这是一直在做的。如果不是这样,您将有浪费的调用链检查每个级别的指针的有效性,如下所示:

void foo(const char * s)
{
    if (s)
        printf("%s", s);
}

void bar(const char * s)
{
    if (s)
        foo(s);
}

void baz(const char * s)
{
    if (s)
        bar(s);
}
于 2013-06-09T12:02:11.843 回答
2

不,你不对。

在第二个代码中,未定义的行为发生在您取消引用指针时,您到达您的函数之前。

这不是您的功能的问题。在你的函数内部,使用第二个签名,你总是可以假设你有一个有效的字符串,这使得它优于第一个。

于 2013-06-09T12:03:43.817 回答