Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 有没有办法禁止在c风格的变量参数列表中使用“按值分类”呢?_C++_C - Fatal编程技术网

C++ 有没有办法禁止在c风格的变量参数列表中使用“按值分类”呢?

C++ 有没有办法禁止在c风格的变量参数列表中使用“按值分类”呢?,c++,c,C++,C,在c风格的无类型变量参数列表中意外使用类是常见的错误源。 例如: 那里的printf调用按值接收两个s对象。这意味着它们的所有成员都是简单的内存复制。但它们被解释为一个简单的字符指针。结果当然是一个运行时错误 我不是在要求解决这个问题,但我希望有一些东西可以添加到我的类中,以便编译器警告我或给出错误 已尝试声明但未实现副本构造函数。但似乎没有调用复制构造函数:-( 请只回答标题中的问题。我不需要讨论为什么不应该使用printf或这些变量参数列表-知道这一点 感谢您的时间。体面的编译器(如gcc)

在c风格的无类型变量参数列表中意外使用类是常见的错误源。 例如:

那里的printf调用按值接收两个s对象。这意味着它们的所有成员都是简单的内存复制。但它们被解释为一个简单的字符指针。结果当然是一个运行时错误

我不是在要求解决这个问题,但我希望有一些东西可以添加到我的类中,以便编译器警告我或给出错误

已尝试声明但未实现副本构造函数。但似乎没有调用复制构造函数:-(


请只回答标题中的问题。我不需要讨论为什么不应该使用printf或这些变量参数列表-知道这一点

感谢您的时间。

体面的编译器(如gcc)检查
printf
参数是否与格式字符串中的格式说明符匹配

不要忘记添加
-Wformat
-Wall
命令行选项


派生自

隐藏复制构造函数和赋值运算符(声明它们为私有,无需实现它们)。或者从boost::noncopyable派生类(具有相同的效果)。按值传递参数决定复制构造函数的用法

“我不需要讨论为什么不应该使用printf或这些变量参数列表-知道这一点。”-printf有什么问题?@mathepic:printf
printf
有一个“错误”:如果将自定义类型作为参数传递,它可以调用UB(如问题中所述)虽然 STD::流的可以优雅地处理它们。但是如果使用得当,则没有什么错误。请检查编译器文档,在这种情况下应该有一个标志来警告它。每当非POD类作为参数传递给具有变量参数的函数时,GC++编译器警告。是吗?@kaptnole他们出于礼貌推迟了,至少是关于你正在经历的问题:)。我知道你不想听到这些,但不要使用printf see advices here@celavek如果你将其作为一个帖子发布,我会接受你的评论作为答案:-)@kaptnole好吧……运气不好:)除了这没有帮助,因为实例不是按值传递的,而是传递了一些原始字节,然后
reinterpret\u cast
-ed to
const char*
。我认为没有语言级别的方法可以避免这种情况。您只能依靠编译器警告(例如“无法通过非POD对象…”)OP在他的问题中已经说过他玩过复制构造函数。你认为重载赋值运算符会改变行为吗?这是VisualC++的一个特性/ bug吗?这相当于C t t林的回答,并且有同样的问题;它不会阻止通过<代码>…<代码>,因为这给了未定义的。行为,而不是复制品。
class MyString {
    public:
    char *pChars;
    int Length;

    MyString(char *pChars) {
        this->pChars = pChars; 
        Length = strlen(pChars); 
        } };

int main() {
    MyString s1("Bla1"), s2("Bla2");
    printf("%s%s", s1, s2); // This does not but should give a compiler warning/error!
    return 0; }