为什么包含循环、递归或被指针调用的函数极易发生内联(inline)
Stanislav Petrov's questions
在“Scott Meyers 有效使用 C++。55 种改进程序结构和代码的可靠方法”一书中的规则 30 中有以下几行:
有时编译器会生成内联函数的主体,即使没有什么阻止它被内联。例如,如果您的程序接收到内置函数的地址,那么编译器通常必须生成函数的实际主体。如果函数不存在,他还能如何获得函数的地址?结合编译器通常不会在指针调用函数时内联这一事实,这意味着对内置函数的调用可能会或可能不会内联,具体取决于它们的调用方式:
inline void f() {...} // предположим, что компилятор может встроить вызовы f
void (*pf)() = f; // pf указывает на f
...
f(); // этот вызов будет встроенным, потому что он
// «нормальный»
pf(); // этот вызов, вероятно, не будет встроен, потому что
// функция вызвана по указателю
即使您从不使用函数指针,非内联内联函数的幽灵也会困扰您,因为不仅仅是程序员可以请求函数指针。有时编译器会生成构造函数和析构函数的非内联副本,以便它们在构造和销毁数组中的对象期间请求函数指针。
目前尚不清楚什么具有指向函数的指针以及数组中对象的破坏。
这两种结构有什么区别。
void Function(int operation(int) ) {}
void Function(int (*operation)(int) ) {}
class Class
{
public:
Class& operator=(const Class&&)
{
return *this;
}
};
int main()
{
Class c1;
Class c3(c1);
return 0;
}
为什么添加到类
Class& operator=(const Class&&)
视觉工作室 2017 写道:
E1776 函数“Class::Class(const Class &)”(隐式声明)不能被引用,因为该函数已被删除
必须有一个标准的复制构造函数。
创建shared_ptr后如何传递指向它的指针?
std::shared_ptr<Investment> createInvestment()
{
std::shared_ptr<Investment> retVal(static_cast<Investment*>(0),
getRidOfInvestment);
// как тут передать в retVal указатель.
return retVal;
}
在https://ru.cppreference.com/w/cpp/algorithm/transform的一篇文章中,我遇到了这种类型转换:
(int (*)(int))std::toupper
如何正确阅读这种类型转换,以及它的用途。
为什么它在第一种情况下起作用而在第二种情况下不起作用,因为在这两种情况下,赋值运算符右侧的类型都是 void *
class A {
public:
void *operator new(size_t size);
void operator delete(void *p);
};
void *A::operator new(size_t size) {
printf("Allocated %d bytes\n", size);
return malloc(size);
}
void A::operator delete(void *p) {
free(p);
}
int main()
{
A* p = new A(); // 1 Почему тут работает
void* v = p;
A* p1 = v; // 2 А тут нет
return 0;
}
在文章http://www.amse.ru/courses/cpp2/2011_03_21.html中,作者写道:
建议不要对
new可能调用new. 例如,要显示文本,请使用函数printf而不是对象std::cout。
这个建议是关于什么的?违反会带来哪些麻烦?
这个设计是什么意思?
static class Class {};
如果构造没有意义,那么工作室为什么要编译它。
我遇到了这行代码:
action="<?=$_SERVER['PHP_SELF']?>"
问号,据我所知,突出显示php代码,问题是为什么在第一个问号之后放置一个等号,如果它没有它就可以工作。
有这样的代码
$mysqli = new mysqli("example.com", "user", "password", "database");
它访问一个不存在的服务器,结果在浏览器中显示:
警告:mysqli::__construct(): (HY000/2002): ������ ���������� ���������� ��� ������ ……………………………………………………………………………………………………………………………………………………………………………………………… �� ������ �������� �� �������� ���� �� ������ ���� ������ �, ���������������������������������� ���������� ��-�� �� �� ������������������������������������。在第 11 行的 C:\OSPanel\domains\mysite.local\index.php
为什么会发生这种情况,如何修复编码。
如果递归函数在单独的子句中没有 return 语句,它会返回什么。
int Recur(int i = 0)
{
if (i != 3) return Recur(++i);
}
Myers 想用下面的代码表达什么。
std::tr1::shared_ptr<Investment> createInvestment()
{
std::tr1::shared_ptr<Investment> retVal(static_cast<Investment*>(0),
getRidOfInvestment);
... // make retVal point to the
// correct object
return retVal;
}
为什么将0传递给retVal,然后如何在返回之前将指针传递给retVal。
迈尔斯从规则中发现了这样一个代码
规则 18:将界面设计为易于使用对,难以使用错误
struct Day { struct Month { struct Year {
explicit Day(int d) explicit Month(int m) explicit Year(int y)
: val(d) {} : val(m) {} : val(y) {}
int val; int val; int val;
}; }; };
这是错版吗?VS 2017 说你不能那样做。
为什么这段代码没有捕捉到异常?
#include <iostream>
class A
{
private:
public:
A()
{
std::cout << "A::A()" << std::endl;
}
~A()
{
throw 1;
std::cout << "A::~A(int)" << std::endl;
}
};
int main()
{
A* p = nullptr;
try
{
p = new A();
delete p;
}
catch(...)
{
std::cout << "catch(...)" << std::endl;
}
return 0;
}
众所周知,end()方法返回最后一个迭代器之后的迭代器,因为在最后一个迭代器之后可以有另一个迭代器,因为最后一个迭代器是最后一个迭代器。
对函数可能实现的代码感兴趣,演示 malloc 函数采用一个参数和 calloc 两个的原因?
这样的鬼能做什么有用的工作?
(void)переменная
