AKL*_*AKL 17 c c++ assembly portability
通过在普通台式PC上运行简单的C ++程序进行基本测试,似乎可以假设任何类型的指针(包括函数指针)的大小等于目标体系结构位的大小。
例如:在32位体系结构中-> 4个字节,在64位体系结构中-> 8个字节。
但是我记得读过的话,它不是一般的那样!
所以我想知道这种情况会怎样?
Eri*_*hil 17
不,假设是不合理的。进行此假设可能会导致错误。
C或C ++中的指针(和整数类型)的大小最终由C或C ++实现确定。普通的C或C ++实现受其目标体系结构和操作系统的影响很大,但它们可能出于执行速度以外的原因而选择其类型的大小,例如支持较小的内存使用,支持未写入代码的目标。完全可移植到任何类型的大小,或者支持更轻松地使用大整数。
我已经看到了针对64位系统但提供32位指针的编译器,目的是构建使用较小内存的程序。(已经观察到,指针的大小是内存消耗的重要因素,这是由于使用了许多具有许多连接的结构以及使用指针的引用。)在假设指针大小等于64位寄存器的情况下编写的源代码大小会破裂。
klu*_*utt 13
合理地假设,通常任何类型的指针(包括指向函数的指针)的大小等于目标体系结构位
要看。如果您打算快速估计内存消耗,那么可能就足够了。
(包括指向函数的指针)
但这是重要的一句话。尽管大多数指针具有相同的大小,但函数指针可能会有所不同。不保证a void*将能够保存函数指针。至少,这对于C是正确的。我不了解C ++。
所以我想知道这种情况会怎样?
原因可能有很多原因。如果您的程序的正确性取决于此大小,则永远无法做这样的假设。而是检查一下。一点也不难。
您可以使用此宏在C编译时检查此类情况:
#include <assert.h>
static_assert(sizeof(void*) == 4, "Pointers are assumed to be exactly 4 bytes");
Run Code Online (Sandbox Code Playgroud)
编译时,会出现错误消息:
$ gcc main.c
In file included from main.c:1:
main.c:2:1: error: static assertion failed: "Pointers are assumed to be exactly 4 bytes"
static_assert(sizeof(void*) == 4, "Pointers are assumed to be exactly 4 bytes");
^~~~~~~~~~~~~
Run Code Online (Sandbox Code Playgroud)
如果您使用的是C ++,则可以跳过,#include <assert.h>因为它static_assert是C ++中的关键字。(并且您可以_Static_assert在C中使用关键字,但是它看起来很丑陋,因此请使用include和宏。)
由于这两行非常容易包含在您的代码中,因此如果您的程序使用错误的指针大小无法正常工作,则没有任何借口不这样做。
合理地假设,任何类型的指针(包括指向函数的指针)的大小通常都等于目标体系结构位?
这可能是合理的,但并非可靠地正确。因此,我猜答案是“否,除非您已经知道答案是(并且不担心可移植性)”。
潜在地:
系统可以具有不同的寄存器大小,并且使用不同的底层宽度进行数据和寻址:“目标体系结构位”对于这种系统甚至意味着什么都不清楚,因此您必须选择特定的ABI(完成后,您必须选择了解该ABI的答案)。
系统可以支持不同的指针模型,如老的near,far和huge指针; 在这种情况下,您需要知道代码在哪种模式下编译(然后您知道该模式的答案)
最后,这种假设没有明显的好处,因为您可以sizeof(T)直接将其用于T感兴趣的任何事情。
如果要在整数和指针之间转换,请使用intptr_t。如果要将整数和指针存储在同一空间中,请使用union。
合理地假设,任何类型的指针(包括指向函数的指针)的大小通常都等于目标体系结构位?
如果您查看当前正在生产的所有类型的CPU(包括微控制器),我会说不。
极端的反例是在同一程序中使用两种不同指针大小的体系结构:
x86,16位
在MS-DOS和16位Windows中,“正常”程序同时使用16位和32位指针。
x86,32位分段
只有少数几个鲜为人知的操作系统使用此内存模型。
程序通常同时使用32位和48位指针。
STM8A
这种现代的汽车8位CPU使用16位和24位指针。当然,两者都在同一程序中。
AVR微小系列
使用8位指针寻址RAM,使用16位指针寻址闪存。
(据我所知,AVR tiny无法用C ++编程。)
| 归档时间: |
|
| 查看次数: |
2140 次 |
| 最近记录: |