• int64_t 在 32 位环境下其实是 long long


    这里说的类型长度指的是相同类型在不同环境下长度不一致的情况,下面总结表格:

    由于这里出现了 32 位和 64 位环境下长度不一致的情况,C 语言特意提供了 stdint.h 头文件 (C++ 中在 cstddef 中引用),定义了定长类型,例如 int64_t 在 32 位环境下其实是 long long,而在 64 位环境下其实是 long。

    但这里的问题点在于:

    • 并没有定长格式符

    例如 uint64_t 在 32 位环境下对应的格式符是 % llu,但是在 64 位环境下对应的格式符是 % lu。有一种折中的解决办法是自定义一个宏:

    1. #if(sizeof(void*) == 8)
    2. #define u64 "%lu"
    3. #else
    4. #define u64 "%llu"
    5. #endif
    6. void demo() {
    7. uint64_t a;
    8. printf("a="u64, a);
    9. }

    但这样会让字符串字面量从中间断开,非常不直观。

    • 类型不一致

    例如在 64 位环境下,long 和 long long 都是 64 位长,但编译器会识别为不同类型,在一些类型推导的场景会出现和预期不一致的情况,例如:

    1. template <typename T>
    2. void func(T t) {}
    3. template <>
    4. void func<int64_t>(int64_t t) {}
    5. void demo() {
    6. long long a;
    7. func(a); // 会匹配通用模板,而匹配不到特例
    8. }

    上述例子表明,func 和 func 是不同实例,尽管在 64 位环境下 long 和 long long 真的看不出什么区别,但是编译器就是会识别成不同类型。

    格式化字符串

    格式化字符串算是非常经典的 C 的产物,不仅是 C++,非常多的语言都是支持这种格式符的,例如 java、Go、python 等等。

    但 C++ 中的格式化字符串可以说完全就是 C 的那一套,根本没有任何扩展。换句话说,除了基本数据类型和 0 结尾的字符串以外,其他任何类型都没有用于匹配的格式符。

    例如,对于结构体类型、数组、元组类型等等,都没法匹配到格式符:

    1. struct Point {
    2. double x, y;
    3. };
    4. void Demo() {
    5. // 打印Point
    6. Point p {1, 2.5};
    7. printf("(%lf,%lf)", p.x, p.y); // 无法直接打印p
    8. // 打印数组
    9. int arr[] = {1, 2, 3};
    10. for (int i = 0; i < 3; i++) {
    11. printf("%d, ", arr[i]); // 无法直接打印整个数组
    12. }
    13. // 打印元组
    14. std::tuple tu(1, 2.5, "abc");
    15. printf("(%d,%lf,%s)", std::get<0>(tu), std::get<1>(tu), std::get<2>(tu)); // 无法直接打印整个元组
    16. }

    对于这些组合类型,我们就不得不手动去访问内部成员,或者用循环访问,非常不方便。

    针对于字符串,还会有一个严重的潜在问题,比如:

    1. std::string str = "abc";
    2. str.push_back('\0');
    3. str.append("abc");
    4. char buf[32];
    5. sprintf(buf, "str=%s", str.c_str());

    由于 str 中出现了 '\0',如果用 % s 格式符来匹配的话,会在 0 的位置截断,也就是说 buf 其实只获取到了 str 中的第一个 abc,第二个 abc 就被丢失了。

  • 相关阅读:
    [ Linux长征路第六篇 ] Linux使用git上传gitee三板斧
    c++异常处理-在构造函数中
    Spring5框架
    26版SPSS操作教程(高级教程第十三章)
    宏观经济学计算题练习
    品牌发力 · 韧性增长 | 数说故事亮相第30届中国国际广告节
    软件加密系统Themida应用程序保护指南(四):虚拟机的选择
    什么是OV SSL证书
    蒸散发与植被总初级生产力的区域数据下载、处理与显示
    Ansible Tower对接ldap和git仓库
  • 原文地址:https://blog.csdn.net/feidodoxcx/article/details/127982292