struct mtd_partition {
const char *name; /* identifier string */
uint64_t size; /* partition size */
uint64_t offset; /* offset within the master MTD space */
};
static struct mtd_partition parts[] = {
{name: "boot", offset: 0, size:0x500000,},
{name: "setting", offset: 0x500000, size:0x300000,},
{name: "linux", offset: 0x800000, size:0x500000,},
{name: "config", offset: 0xd00000, size:0x100000,},
{name: "rootfs", offset: 0xe00000, size:0x3200000,},
{name: "app", offset: 0x4e00000, size:0x800000,},
};
static struct resource pxa27x_resource_ohci[] = {
[0] = {
.start = 0x4C000000,
.end = 0x4C00ff6f,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_USBH1,
.end = IRQ_USBH1,
.flags = IORESOURCE_IRQ,
},
};
这些方法虽然不知道是C的哪个标准引入的,但是见到有代码这样用。
sanitizers是Google推出的调试工具。已集成到各主流编译器之中,无需安装。
代码:
https://github.com/google/sanitizers
参考:
https://zhuanlan.zhihu.com/p/257939964
编译器自带的调试神器sanitizers
spaceship operator: <=>
C++20引入了spaceship operator:
a<b
,返回std::strong_ordering::less。a>b
,返回std::strong_ordering::greater。这和strcmp
的设计理念类似。
此外,还有关系运算符的重载推导,定义了<=>
之后,其他诸如==
、!=
、<
、<=
、>
、>=
的关系运算自动成立,无需再写相应的重载函数了。同理,如果定义了==
,那么!=
就自动成立了。
参考:
https://cloud.tencent.com/developer/article/1352324
C++20草案中的宇宙飞船运算符(<=>,spaceship operator)
线程安全注解是现代C++开发的机制,可以在代码编译阶段检查锁的使用情况,从而发现线程同步的相关问题。该功能目前只有clang编译器支持。
https://blog.csdn.net/qq_32648921/article/details/109114887
线程安全注解
Implementation-defined:C标准没有明确规定,但是要求编译器必须对此做出明确规定,并写在编译器的文档中。
Unspecified:C标准没有明确规定,编译器可以自己决定,不必写在编译器的文档中。
Undefined:C标准没规定怎么处理,编译器很可能也没规定。
https://www.cnblogs.com/MagicLetters/archive/2011/08/03/2126471.html
C语言中关于Implementation-defined、Unspecified和Undefined
struct CLS
{
int m_i;
CLS( int i ) : m_i(i){}
CLS()
{
CLS(0);
}
};
如上,在CLS()
调用CLS(0);
会创建一个新的临时对象,达不到重载的目的。
应该怎么做呢?new (this)CLS(0);
https://www.cnblogs.com/stemon/p/4834043.html
在构造函数内部调用构造函数
如果基类析构函数不是虚函数,则当通过父类指针或引用指向子类时,在调用析构函数时只调用父类的析构函数,所以只释放父类在堆区开辟的内存,子类在堆区开辟的内存没有被释放。
string test()
{
return "abc";
}
int main()
{
const char *p = test().c_str();
cout << p << endl;
return 0;
}
string("abc")
是一个临时对象,在执行完const char *p = string("abc").c_str();
这个语句后,临时对象就析构了,而不会等到块结束。
https://blog.csdn.net/stpeace/article/details/46461167
聊聊C++临时对象的析构时间点
switch (reg) {
case TAS5086_CLOCK_CONTROL ... TAS5086_BKNDERR:
return 1;
case TAS5086_INPUT_MUX:
case TAS5086_PWM_OUTPUT_MUX:
return 4;
}
可以用上面的办法,少写一些case语句。
https://www.zhihu.com/question/300975864
为什么很多程序员不用 switch,而是大量的 if…else if …?
对于要求严格位宽的场合,应用程序可以使用uint8_t,uint16_t,uint32_t来获得移植时的一致性。它的头文件是inttypes.h。
https://blog.csdn.net/qq_38231713/category_10001159.html
一个C++11并发与多线程的专栏
在C语言的函数定义上,我们通常用的函数定义方式为ANSI C的函数定义方式。但是在C语言之父创立C语言之时,函数的定义形式并非现在我们所见到的形式。
这种风格被称为K&R风格,多见于一些历史悠久的项目或者老的书籍中。出于兼容性考虑,现代的C编译器仍然支持K&R风格。
记得大学学C语言,用的是谭浩强的书。当时,授课老师看不上谭的书,于是另外推荐了一本,那本书更古老,用的就是所谓的K&R风格。。。但在实际工作中,从来没见过K&R风格的代码。。。
详见:
http://blog.chinaunix.net/uid-7426920-id-2627743.html
ANSI和K&R两种函数定义风格
SFINAE:Substitution failure is not an error
https://en.cppreference.com/w/cpp/language/sfinae
官方文档
https://zhuanlan.zhihu.com/p/21314708
C++模板进阶指南:SFINAE
auto vec = make_index_vector(std::make_index_sequence<10>());
for(auto i : vec) {std::cout << i << ' ';}
std::cout << std::endl;
std::iota(vec.begin(), vec.end(), 999);
std::copy(vec.begin(), vec.end(), std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
std::for_each(std::begin(vec),std::end(vec),[](int n){std::cout<<n<<" ";});
std::cout << std::endl;
两者都是动态分配内存。
主要的不同:malloc不初始化分配的内存,已分配的内存中可以是任意的值。calloc初始化已分配的内存为0。
次要的不同:calloc返回的是一个数组,而malloc返回的是一个对象。
常用的malloc实现主要有:
在多线程环境使用tcmalloc和jemalloc效果非常明显。
当线程数量固定,不会频繁创建退出的时候, 可以使用jemalloc;反之使用tcmalloc可能是更好的选择。
malloc是用户层面而不是系统层面的东西,系统调用里并没有malloc。
https://www.cnblogs.com/cthon/p/10563946.html
内存优化总结:ptmalloc、tcmalloc和jemalloc
std::vector<int> return_vector(void)
{
std::vector<int> tmp {1,2,3,4,5};
return tmp;
}
std::vector<int> rval_ref = return_vector();
如果按照一般的返回值传递的规则,tmp作为局部变量是传不到外面去的,因此返回的时候,会在外部创建一个同类型的变量,并将tmp的内容复制过去。从而带来了一次复制的开销。
RVO(Return Value Optimization)就是用来优化这种情况的。上述代码执行RVO之后,就等价于:
void return_vector(std::vector<int>& tmp)
{
tmp = std::vector<int>({1,2,3,4,5});
}
std::vector<int> rval_ref;
return_vector(rval_ref);
https://www.zhihu.com/question/27000013
什么时候应当依靠返回值优化(RVO)?
class Base
{
public:
void something(Base& b){}
};
int main()
{
Base b;
b.something(Base());
return 0;
}
上面的代码在编译时,会出现如下错误信息:
abc.cpp:12:20: error: no matching function for call to ‘Base::something(Base)’
abc.cpp:12:20: note: candidate is:
abc.cpp:6:7: note: void Base::something(Base&)
abc.cpp:6:7: note: no known conversion for argument 1 from ‘Base’ to ‘Base&’
这是由于Base()
生成的是临时变量,将之赋值给一个non-const的引用是不行的。
解决方法是
void something(const Base& b){}
可以参看下文:
http://stackoverflow.com/questions/20247525/about-c-conversion-no-known-conversion-for-argument-1-from-some-class-to
有些类库出于兼容性的考虑,仍然保留了对旧函数的支持。但是继续使用这些函数,显然不是作者的初衷。因此,有必要在编译时,给出废弃的提示。
近日浏览cocos2d-x v3的代码,发现可以这样做:
宏定义:
#if defined(__GNUC__) && ((__GNUC__ >= 4) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1)))
#define CC_DEPRECATED_ATTRIBUTE __attribute__((deprecated))
#elif _MSC_VER >= 1400 //vs 2005 or higher
#define CC_DEPRECATED_ATTRIBUTE __declspec(deprecated)
#else
#define CC_DEPRECATED_ATTRIBUTE
#endif
宏使用:
CC_DEPRECATED_ATTRIBUTE static TextureCache * getInstance();
auto tuple = std::make_tuple(1, 'A', "test");
std::cout << std::get<0>(tuple) << std::endl;
std::cout << std::get<1>(tuple) << std::endl;
std::cout << std::get<2>(tuple) << std::endl;
可用tuple或pair返回多个返回值,然后用tie进行解包。这里的语法非常类似python。
std::pair<int, std::string> fun_tie(int a, std::string str)
{
return std::make_pair(a, str);
}
int a;
std::string str;
std::tie(a , str) = fun_tie(12, std::string("Pony Ma"));
std::cout << a << "," << str << std::endl;
https://github.com/fffaraz/awesome-cpp
一个专门收集各种C/C++库的网页
https://github.com/gabime/spdlog
一个C++的log库
https://zhuanlan.zhihu.com/p/674073158
超详细!spdlog源码解析
vector<bool>
并不是一个通常意义上的vector容器,这个源自于历史遗留问题。 早在C++98的时候,就有vector< bool>
这个类型了,但是因为当时为了考虑到节省空间的想法,所以vector<bool>
里面不是一个Byte一个Byte储存的,它是一个bit一个bit储存的!
https://www.zhihu.com/question/23367698
c++中为什么不提倡使用vector<bool>
?
struct Test {
int a;
int b;
char c[0];
};
Zero-length array不占用结构体的空间,但可以由编译器计算offset,例如上例中指向c的指针,实际上指向了整个结构体的尾部(不含结构体本身)。
您的打赏,是对我的鼓励