C++ определенные недопустимые операции происходит
Они начинают работу, операции Кода С++ определяют, допустимы ли операции. Проверки ищут область значений недопустимых поведений:
Размер массивов не строго положителен.
Оператор typeid
разыменовывает указатель NULL
.
Оператор dynamic_cast
выполняет недопустимый бросок.
(C++ 11 и вне), количество пунктов инициализатора массивов превышает количество элементов массива, чтобы инициализировать.
Рассмотрите и зафиксируйте недопустимый C++ определенные проверки операций
class License { protected: int numberOfUsers; char (*userList)[20]; int *licenseList; public: License(int numberOfLicenses); void initializeList(); char* getUser(int); int getLicense(int); }; License::License(int numberOfLicenses) : numberOfUsers(numberOfLicenses) { userList = new char [numberOfUsers][20]; licenseList = new int [numberOfUsers]; initializeList(); } int getNumberOfLicenses(); int getIndexForSearch(); void main() { int n = getNumberOfLicenses(); if(n >= 0 && n <= 100) { License myFirm(n); int index = getIndexForSearch(); myFirm.getUser(index); myFirm.getLicense(index); } }
В этом примере аргументе n
конструктору License::License
попадает в две категории:
n = 0
: Когда оператор new
использует этот аргумент, Invalid C++ specific operations производят ошибку.
n > 0
: Когда оператор new
использует этот аргумент, Invalid C++ specific operations является зеленым.
Комбинирование двух категорий аргументов, Invalid C++ specific operations производит оранжевую ошибку на операторе new
.
typeid
, разыменовывающий указатель NULL
Чтобы видеть эту проблему, включите опции Consider environment pointers as unsafe (-stubbed-pointers-are-unsafe)
.
#include <iostream>
#include <typeinfo>
#define PI 3.142
class Shape {
public:
Shape();
virtual void setVal(double) = 0;
virtual double area() = 0;
};
class Circle: public Shape {
double radius;
public:
Circle(double radiusVal):Shape() {
setVal(radiusVal);
}
void setVal(double radiusVal) {
radius = radiusVal;
}
double area() {
return (PI * radius * radius);
}
};
Shape* getShapePtr();
void main() {
Shape* shapePtr = getShapePtr();
double val;
if(typeid(*shapePtr)==typeid(Circle)) {
std::cout<<"Enter radius:";
std::cin>>val;
shapePtr->setVal(val);
std::cout<<"Area of circle = "<<shapePtr->area();
}
else {
std::cout<<"Shape is not a circle.";
}
}
В этом примере указатель Shape*
shapePtr
, возвращенным функцией getShapePtr()
, может быть NULL
. Поскольку возможно NULL
- оценил shapePtr
, используется с оператором typeid
, проверка Invalid C++ specific operations является оранжевой.
dynamic_cast
на указателяхclass Base { public : virtual void func() ; }; class Derived : public Base { }; Base* returnObj(int flag) { if(flag==0) return new Derived; else return new Base; } int main() { Base * ptrBase; Derived * ptrDerived; ptrBase = returnObj(0) ; ptrDerived = dynamic_cast<Derived*>(ptrBase); //Correct dynamic cast assert(ptrDerived != 0); //Returned pointer is not null ptrBase = returnObj(1); ptrDerived = dynamic_cast<Derived*>(ptrBase); //Incorrect dynamic cast // Verification continues despite red assert(ptrDerived == 0); //Returned pointer is null }
В этом примере Invalid C++ specific operations на операторе dynamic_cast
:
Зеленый, когда указатель ptrBase
, что броски оператора к Derived
уже указывают на объект Derived
.
Красный, когда указатель ptrBase
, что броски оператора к Derived
указывают на объект Base
.
Красные проверки обычно останавливают верификацию в том же осциллографе как проверка. Однако после красного Invalid C++ specific operations на операции dynamic_cast
включающие указатели, верификация продолжается. Программное обеспечение принимает, что оператор dynamic_cast
возвращает указатель NULL
.
dynamic_cast
на ссылкахclass Base { public : virtual void func() ; }; class Derived : public Base { }; Base& returnObj(int flag) { if(flag==0) return *(new Derived); else return *(new Base); } int main() { Base & refBase1 = returnObj(0); Derived & refDerived1 = dynamic_cast<Derived&>(refBase1); //Correct dynamic cast; Base & refBase2 = returnObj(1); Derived & refDerived2 = dynamic_cast<Derived&>(refBase2); //Incorrect dynamic cast // Analysis stops assert(1); }
В этом примере Invalid C++ specific operations на операторе dynamic_cast
:
Зеленый, когда ссылочный refBase1
, который броски оператора к Derived&
уже отсылают к объекту Derived
.
Красный, когда ссылочный refBase2
, который броски оператора к Derived&
отсылают к объекту Base
.
После красного Invalid C++ specific operations на операции dynamic_cast
включающие указатели программное обеспечение не проверяет код в том же осциллографе как проверка. Например, программное обеспечение не выполняет проверку User assertion на операторе assert
.
#include <stdio.h> int* arr_const; void allocate_consts(int size) { if(size>1) arr_const = new int[size]{0,1,2}; else if(size==1) arr_const = new int[size]{0,1}; else printf("Nonpositive array size!"); } int main() { allocate_consts(3); allocate_consts(1); return 0; }
В этом примере проверка Invalid C++ specific operations определяет, совпадает ли количество пунктов инициализатора с числом элементов, чтобы инициализировать.
В первом вызове allocate_consts
список инициализаций имеет три элемента, чтобы инициализировать массив размера три. Invalid C++ specific operations начинает работу, оператор new
является зеленым. Во втором вызове список инициализаций имеет два элемента, но инициализирует массив размера один. Проверка на операторе new
является красной.
Группа: C++ |
Язык: C++ |
Акроним: CPP |
1. Если смысл перевода понятен, то лучше оставьте как есть и не придирайтесь к словам, синонимам и тому подобному. О вкусах не спорим.
2. Не дополняйте перевод комментариями “от себя”. В исправлении не должно появляться дополнительных смыслов и комментариев, отсутствующих в оригинале. Такие правки не получится интегрировать в алгоритме автоматического перевода.
3. Сохраняйте структуру оригинального текста - например, не разбивайте одно предложение на два.
4. Не имеет смысла однотипное исправление перевода какого-то термина во всех предложениях. Исправляйте только в одном месте. Когда Вашу правку одобрят, это исправление будет алгоритмически распространено и на другие части документации.
5. По иным вопросам, например если надо исправить заблокированное для перевода слово, обратитесь к редакторам через форму технической поддержки.