C++ IB & UB

● **IB: Implementation-defined Behaviour. **The standard leaves it up to the particular compiler/platform to define the precise behaviour, but requires that it be defined.

○ Using implementation-defined behaviour can be useful, but makes your code less portable.

● **UB: Unspecified Behavior. **behavior, for a well-formed program construct and correct data, that depends on the implementation.

○ Note: The implementation is not required to document which behavior occurs.

● **UB: Undefined Behaviour. **The standard does not specify how a program invoking undefined behaviour should behave. Also known as "nasal demons" because theoretically it could make demons fly out of your nose.

○ Using undefined behaviour is nearly always a bad idea. Even if it seems to work sometimes, any change to environment, compiler or platform can randomly break your code.

IB: Implementation-defined Behaviour

  • the exact size of fundamental types such as int and long
  • definition of the NULL macro (possibly 0, ((void*)0), or nullptr)
  • conversions between pointers and integers (reinterpret_caststd::uintptr_t(...))
  • nesting limit for #include directives
  • choice of larger or smaller value for float literals (round up or down if necessary)
  • operating systems on which implementation depends
  • value of pow(0,0) (usually 1)

UB: Unspecified Behavior

  • whether all string literals are distinct (they might have different addresses)
  • the initial value of storage allocated by new (often zero when getting new memory from the OS)
  • evaluation order of operands of some operators (for A + B, B might be evaluated before A)
  • amount of time it takes for a thread to make progress (but eventual progress is guaranteed)
  • whether references require any storage (they usually do, just like pointers)

UB: Undefined Behaviour

Pointer

  • Dereferencing a NULL pointer
  • Dereferencing a pointer returned by a "new" allocation of size zero
  • Using pointers to objects whose lifetime has ended (for instance, stack allocated objects or deleted objects)
  • Dereferencing a pointer that has not yet been definitely initialized
  • Performing pointer arithmetic that yields a result outside the boundaries (either above or below) of an array.
  • Dereferencing the pointer at a location beyond the end of an array.
  • Converting pointers to objects of incompatible types
  • Using memcpy to copy overlapping buffers.

Buffer overflows

  • Reading or writing to an object or array at an offset that is negative, or beyond the size of that object (stack/heap overflow)

Integer Overflows

  • Signed integer overflow
  • Evaluating an expression that is not mathematically defined
  • Left-shifting values by a negative amount (right shifts by negative amounts are implementation-defined)
  • Shifting values by an amount greater than or equal to the number of bits in the number (e.g. int64_t i = 1; i <<= 72 is undefined)

Types, Cast and Const

  • Casting a numeric value into a value that can't be represented by the target type (either directly or via static_cast)
  • Using an automatic variable before it has been definitely assigned (e.g., int i; i++; cout << i;)
  • Using the value of any object of type other than volatile or sig_atomic_t at the receipt of a signal
  • Attempting to modify a string literal or any other const object during its lifetime
  • Concatenating a narrow with a wide string literal during preprocessing

Function and Template

  • Not returning a value from a value-returning function (directly or by flowing off from a try-block)
  • Multiple different definitions for the same entity (class, template, enumeration, inline function, static member function, etc.)
  • Infinite recursion in the instantiation of templates
  • Calling a function using different parameters or linkage to the parameters and linkage that the function is defined as using.

OOP

  • Cascading destructions of objects with static storage duration
  • The result of assigning to partially overlapping objects
  • Recursively re-entering a function during the initialization of its static objects
  • Making virtual function calls to pure virtual functions of an object from its constructor or destructor
  • Referring to nonstatic members of objects that have not been constructed or have already been destructed
  • Calling exit during the destruction of a program with static storage duration

Source file and Preprocessing

  • A non-empty source file that doesn't end with a newline, or ends with a backslash (prior to C++11)
  • A backslash followed by a character that is not part of the specified escape codes in a character or string constant (this is implementation-defined in C++11).
  • Exceeding implementation limits (number of nested blocks, number of functions in a program, available stack space ...)
  • Preprocessor numeric values that can't be represented by a long int
  • Preprocessing directive on the left side of a function-like macro definition
  • Dynamically generating the defined token in a #if expression
相关推荐
MSTcheng.4 小时前
【C++】C++异常
java·数据库·c++·异常
草莓熊Lotso5 小时前
Linux 文件描述符与重定向实战:从原理到 minishell 实现
android·linux·运维·服务器·数据库·c++·人工智能
历程里程碑5 小时前
Linux22 文件系统
linux·运维·c语言·开发语言·数据结构·c++·算法
在路上看风景12 小时前
19. 成员初始化列表和初始化对象
c++
zmzb010313 小时前
C++课后习题训练记录Day98
开发语言·c++
念风零壹13 小时前
C++ 内存避坑指南:如何用移动语义和智能指针解决“深拷贝”与“内存泄漏”
c++
孞㐑¥14 小时前
算法——BFS
开发语言·c++·经验分享·笔记·算法
MZ_ZXD00116 小时前
springboot旅游信息管理系统-计算机毕业设计源码21675
java·c++·vue.js·spring boot·python·django·php
A星空12316 小时前
一、Linux嵌入式的I2C驱动开发
linux·c++·驱动开发·i2c
凡人叶枫17 小时前
C++中智能指针详解(Linux实战版)| 彻底解决内存泄漏,新手也能吃透
java·linux·c语言·开发语言·c++·嵌入式开发