我正在寻找C89/C90标准的免费版本,但我无法在任何地方找到它!为什么这么难找?
C99和C11标准很容易在互联网上获得.即使在Stack Overflow问题中,我在哪里可以找到当前的C或C++标准文档?在C标准中,获得标准不包含我正在寻找的内容.
网络搜索既没有帮助,也没有开放标准.
我有这个代码:
int main()
{
vector<int> res;
res.push_back(1);
vector<int>::iterator it = res.begin();
for( ; it != res.end(); it++)
{
it = res.erase(it);
//if(it == res.end())
// return 0;
}
}
Run Code Online (Sandbox Code Playgroud)
"一个随机访问迭代器,指向函数调用擦除的最后一个元素之后的元素的新位置,如果操作擦除了序列中的最后一个元素,则为向量结束."
此代码崩溃,但如果我使用if(it == res.end())然后返回它的工作原理.怎么会?for循环是否兑现了res.end(),因此不相等的运算符失败了?
我是C/C++的新手,所以我对基本类型有几个问题:
a)你能解释一下int64_t和long(long int)之间的区别吗?据我所知,两者都是64位整数.有没有理由选择一个而不是另一个?
b)我试图int64_t在网上查找定义,但没有取得多大成功.我是否需要咨询这些问题的权威来源?
c)对于使用int64_t编译的代码,我目前包括<iostream>,这对我来说没有多大意义.还有其他包含提供声明int64_t吗?
请查看以下异常抛出和捕获:
void some_function() {
throw std::exception("some error message");
}
int main(int argc, char **argv) {
try {
some_function();
} catch (const std::exception& e) {
std::cerr << e.what() << std::endl;
exit(1);
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
通过引用捕获抛出的异常是否安全?
我担心的是因为异常e实际上是放在堆栈上的some_function().但some_function()刚刚回来,导致e被破坏.所以实际上现在e指向一个被破坏的对象.
我的担忧是否正确?
传递异常而不按值复制它的正确方法是什么?我应该抛出new std::exception()它放在动态内存中吗?
以下代码片段(正确)在C中发出警告,在C++中发出错误(分别使用gcc和g ++,使用版本3.4.5和4.2.1进行测试; MSVC似乎并不关心):
char **a;
const char** b = a;
Run Code Online (Sandbox Code Playgroud)
我能理解并接受这个.
这个问题的C++解决方案是将b更改为const char*const*,它不允许重新分配指针并阻止你绕过const-correctness(C++ FAQ).
char **a;
const char* const* b = a;
Run Code Online (Sandbox Code Playgroud)
但是,在纯C中,更正后的版本(使用const char*const*)仍会发出警告,我不明白为什么.有没有办法绕过这个而不使用演员?
澄清:
1)为什么这会在C中产生警告?它应该完全是const安全的,并且C++编译器似乎认识到它.
2)在说(并让编译器强制执行)我不会修改它指向的字符时,接受这个char**作为参数的正确方法是什么?例如,如果我想写一个函数:
void f(const char* const* in) {
// Only reads the data from in, does not write to it
}
Run Code Online (Sandbox Code Playgroud)
我想在char**上调用它,参数的正确类型是什么?
编辑:感谢那些做出回应的人,特别是那些提出问题和/或跟进我的回复的人.
我已经接受了这样一个答案,即如果没有演员阵容,我想做的事情是无法完成的,无论是否应该这样做.
在[except.ctor]中,标准(N4140)保证:
...自从输入try块以来构造的所有自动对象都会调用析构函数...
但是在下面的例子中,空输出证明函数的返回值foo没有被破坏,尽管它已被构造.使用g ++(5.2.1)和clang ++(3.6.2-1)以及选项编译-O0 -fno-elide-constructors -std=c++14.
struct A { ~A() { cout << "~A\n"; } };
struct B { ~B() noexcept(false) { throw 0; } };
A foo() {
B b;
return {};
}
int main() {
try { foo(); }
catch (...) { }
}
Run Code Online (Sandbox Code Playgroud)
这是g ++和clang ++中的错误,还是函数返回值不被视为自动对象,还是C++语言中的循环漏洞?
在[stmt.return],[expr.call]或[dcl.fct]中都没有找到一个明确的语句,函数返回值是否被视为自动对象.我找到的最接近的提示是6.3.3 p2:
......退货声明可能涉及临时物体的构造和复制或移动......
和5.2.2 p10:
如果结果类型是左值引用类型或对函数类型的右值引用,则函数调用是左值;如果结果类型是对象类型的右值引用,则为xvalue,否则为prvalue.
似乎有许多关于指针与参考的相关问题,但我找不到我想知道的东西.基本上,一个对象通过引用传入:
funcA(MyObject &objRef) { ... }
Run Code Online (Sandbox Code Playgroud)
在函数中,我可以获得指向该对象而不是引用的指针吗?如果我将引用objRef视为别名MyObject,&objRef实际上会给我一个指向MyObject的指针吗?这似乎不太可能.我很迷惑.
编辑:经过仔细检查,objRef确实给了我指向我需要的对象的指针 - 大多数人给了我正确的信息/答案,非常感谢.在这种情况下,我提出了似乎最具说明性的答案.
可能重复:
我在哪里可以找到当前的C或C++标准文档?
我在哪里可以找到完整的C++ 11标准?我知道它的特征是漂浮在互联网上,但我似乎无法找到文件本身.
来自Stroustrup的TC++ PL,第3版,第21.3.3节:
如果我们尝试读入变量v并且操作失败,则v的值应该保持不变(如果v是istream或ostream成员函数处理的类型之一,则它不会改变).
以下示例似乎与上述引用相矛盾.基于上面的引用,我期待v的值保持不变 - 但它会变为零.对这种明显的矛盾行为有什么解释?
#include <iostream>
#include <sstream>
int main( )
{
std::stringstream ss;
ss << "The quick brown fox.";
int v = 123;
std::cout << "Before: " << v << "\n";
if( ss >> v )
{
std::cout << "Strange -- was successful at reading a word into an int!\n";
}
std::cout << "After: " << v << "\n";
if( ss.rdstate() & std::stringstream::eofbit ) std::cout << "state: eofbit\n";
if( ss.rdstate() & std::stringstream::failbit ) std::cout << "state: failbit\n"; …Run Code Online (Sandbox Code Playgroud) 这个程序是否定义明确,如果没有,为什么呢?
#include <iostream>
#include <new>
struct X {
int cnt;
X (int i) : cnt(i) {}
~X() {
std::cout << "destructor called, cnt=" << cnt << std::endl;
if ( cnt-- > 0 )
this->X::~X(); // explicit recursive call to dtor
}
};
int main()
{
char* buf = new char[sizeof(X)];
X* p = new(buf) X(7);
p->X::~X(); // explicit call to dtor
delete[] buf;
}
Run Code Online (Sandbox Code Playgroud)
我的推理:虽然两次调用析构函数是未定义的行为,但按照12.4/14,它的确如此:
如果为生命周期结束的对象调用析构函数,则行为未定义
这似乎并没有禁止递归调用.当对象的析构函数正在执行时,对象的生命周期尚未结束,因此再次调用析构函数不是UB.另一方面,12.4/6说:
执行body [...]后,类X的析构函数调用X的直接成员的析构函数,X的直接基类的析构函数[...]
这意味着在从析构函数的递归调用返回之后,将调用所有成员和基类析构函数,并在返回到上一级递归时再次调用它们将是UB.因此,没有基数且只有POD成员的类可以具有不带UB的递归析构函数.我对吗?
c++ ×8
c ×3
ansi ×1
c++11 ×1
c89 ×1
cin ×1
const ×1
destructor ×1
exception ×1
integer ×1
iterator ×1
long-integer ×1
pointers ×1
return ×1
return-value ×1
state ×1
stringstream ×1
vector ×1