2

我遇到了一个函数,这样它就可以区分被称为

foo("bar");

对比

const char *bob = "bar";
foo(bob);

我想到的可能性是:

  • 字符串地址:两个参数都位于图像的 .rdata 部分。如果我在同一个程序中进行两个调用,两个调用都会收到相同的字符串地址。
  • RTTI:不知道如何使用 RTTI 来检测这种差异。

我能想到的唯一可行的例子是:

void foo(char *msg)
{
    printf("string literal");
}

void foo(const char *&msg)
{
    printf("string pointer");
}

foo("bar");                 // "string literal"

const char *soap = "bar";
foo(soap);                  // "string pointer"

我无权访问函数的代码,头文件中的声明只显示了一个函数声明。

4

3 回答 3

5

这是区分字符串文字和指针的另一种方法,基于字符串文字具有数组类型而不是指针类型的事实:

#include <iostream>

void foo(char *msg)
{
    std::cout << "non-const char*\n";
}

void foo(const char *&msg) // & needed, else this is preferred to the
                           // template function for a string literal
{
    std::cout << "const char*\n";
}

template <int N>
void foo(const char (&msg)[N])
{
    std::cout << "const char array reference ["<< N << "]\n";
}

int main() {
    foo("bar"); // const char array reference [4]
}

但请注意,所有这些(包括您的原始函数)都可以通过传递不是字符串文字的东西来“愚弄”:

const char *soap = 0;
foo(soap);

char *b = 0;
foo(b);

const char a[4] = {};
foo(a);

C++ 中没有字符串文字独有的类型。因此,您可以使用类型来区分数组和指针,但不能区分字符串文字和另一个数组。RTTI 没有用,因为 RTTI 只存在于具有至少一个虚拟成员函数的类。其他任何事情都取决于实现:标准中不保证字符串文字将占用任何特定的内存区域,或者在程序中(甚至在编译单元中)使用两次的相同字符串文字将具有相同的地址。就存储位置而言,实现可以用字符串文字做的任何事情,也可以用我的 array 做a

于 2010-08-26T23:38:01.997 回答
1

该函数foo()理论上可以使用宏来确定参数是否为文字。

#define foo(X) (*#X == '"'
                ? foo_string_literal(X)
                : foo_not_string_literal(X))
于 2013-09-25T21:45:21.603 回答
0

如果您将其称为:

const char bob[] = "bar";
foo(bob);

它可能正在使用某种类似的区别来做出决定。

编辑:如果标头中只有一个函数声明,我无法想象任何可移植的方式库可以做出这种区分。

于 2010-08-26T17:27:27.850 回答