求帮助,宏重定义及“java struct类型”类型重定义

二次元同好交流新大陆
扫码下载App
汇聚2000万达人的兴趣社区下载即送20张免费照片冲印
扫码下载App
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!&&|&&
LOFTER精选
网易考拉推荐
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
阅读(8733)|
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
历史上的今天
在LOFTER的更多文章
loftPermalink:'',
id:'fks_082071',
blogTitle:'VC编译错误:error C2011: “fd_set”: “struct”类型重定义
d:\\program files\\microsoft visual studio 8\\vc\\platformsdk\\include\\winsock.h(54) : 参见“fd_set”的声明',
blogAbstract:'1&d:\\program files\\microsoft visual studio 8\\vc\\platformsdk\\include\\winsock2.h(112) : error C2011: “fd_set”: “struct”类型重定义1&&&&&&&& d:\\program files\\microsoft visual studio 8\\vc\\platformsdk\\include\\winsock.h(54) : 参见“fd_set”的声明1&d:\\program files\\microsoft visual studio 8\\vc\\platformsdk\\include\\winsock2.h(147) : warning C4005: “FD_SET”: 宏重定义',
blogTag:'',
blogUrl:'blog/static/',
isPublished:1,
istop:false,
modifyTime:8,
publishTime:9,
permalink:'blog/static/',
commentCount:1,
mainCommentCount:1,
recommendCount:0,
bsrk:-100,
publisherId:0,
recomBlogHome:false,
currentRecomBlog:false,
attachmentsFileIds:[],
groupInfo:{},
friendstatus:'none',
followstatus:'unFollow',
pubSucc:'',
visitorProvince:'',
visitorCity:'',
visitorNewUser:false,
postAddInfo:{},
mset:'000',
remindgoodnightblog:false,
isBlackVisitor:false,
isShowYodaoAd:true,
hostIntro:'',
hmcon:'1',
selfRecomBlogCount:'0',
lofter_single:''
{list a as x}
{if x.moveFrom=='wap'}
{elseif x.moveFrom=='iphone'}
{elseif x.moveFrom=='android'}
{elseif x.moveFrom=='mobile'}
${a.selfIntro|escape}{if great260}${suplement}{/if}
{list a as x}
推荐过这篇日志的人:
{list a as x}
{if !!b&&b.length>0}
他们还推荐了:
{list b as y}
转载记录:
{list d as x}
{list a as x}
{list a as x}
{list a as x}
{list a as x}
{if x_index>4}{break}{/if}
${fn2(x.publishTime,'yyyy-MM-dd HH:mm:ss')}
{list a as x}
{if !!(blogDetail.preBlogPermalink)}
{if !!(blogDetail.nextBlogPermalink)}
{list a as x}
{if defined('newslist')&&newslist.length>0}
{list newslist as x}
{if x_index>7}{break}{/if}
{list a as x}
{var first_option =}
{list x.voteDetailList as voteToOption}
{if voteToOption==1}
{if first_option==false},{/if}&&“${b[voteToOption_index]}”&&
{if (x.role!="-1") },“我是${c[x.role]}”&&{/if}
&&&&&&&&${fn1(x.voteTime)}
{if x.userName==''}{/if}
网易公司版权所有&&
{list x.l as y}
{if defined('wl')}
{list wl as x}{/list}为什么会报错(在VC6中编译运行):
'_INPUT_RECORD' : 'struct' type redefinition
'_MOUSE_EVENT_RECORD' : 'struct' type redefinition
我已经在前面引用了:
#include &stdio.h&
#include &windows.h&
下面就是struct。
typedef struct _INPUT_RECORD { //出错的地方
WORD EventT
KEY_EVENT_RECORD KeyE
MOUSE_EVENT_RECORD MouseE
WINDOW_BUFFER_SIZE_RECORD WindowBufferSizeE
MENU_EVENT_RECORD MenuE
FOCUS_EVENT_RECORD FocusE
} INPUT_RECORD;
typedef struct _MOUSE_EVENT_RECORD { //出错的地方
COORD dwMouseP
DWORD dwButtonS
DWORD dwControlKeyS
DWORD dwEventF
} MOUSE_EVENT_RECORD;
另外,标识符的下划线前缀,只存在编程策略的人为限制,并不存在语言本身规则的限制,所以,本问题的原因,一如编译器的提示:
'_INPUT_RECORD' : 'struct' type redefinition
'_MOUSE_EVENT_RECORD' : 'struct' type redefinition
你所使用的标识符:"_INPUT_RECORD"以及"_MOUSE_EVENT_RECORD"声明已经在可能的名字空间中存在,对于VC6而言,这两个标识符已经在wincon.h中有了声明。
解决之道不言而喻:
_INPUT_RECORDx和_MOUSE_EVENT_RECORDx
上述修改已经编译测试,可用!
带两个下划线的标识符留给C++编译程序使用.
带一个下划线的名字也要避免使用,国为他们保留给命名操作系统例程的某些C的实现.
typedef struct _INPUT_RECORD {& WORD EventT& union {&&& KEY_EVENT_RECORD KeyE&&& MOUSE_EVENT_RECORD MouseE&&& WINDOW_BUFFER_SIZE_RECORD WindowBufferSizeE&&& MENU_EVENT_RECORD MenuE&&& FOCUS_EVENT_RECORD FocusE& } E
} INPUT_RECORD;
Declared in Wincon.h; include Windows.h.
你看下是否重复定义了。
已解决问题
未解决问题写宏定义:得到一个field在结构体struct type中的偏移量转
/tian_/blog/item/77fd7afa5ffcc29d59ee90ba.html
#define OFFSETOF(type, field) ((size_t)&(((type *)0)-&field))
(type *)0:把0地址当成type类型的指针。
((type *)0)-&field:对应域的变量。
&((type *)0)-&field:取该变量的地址,其实就等于该域相对于0地址的偏移量。
(size_t)&(((type *)0)-&field):将该地址(偏移量)转化为size_t型数据。
ANSI C标准允许任何值为0的常量被强制转换成任何一种类型的指针,并且转换结果是一个NULL指针,因此((s*)0)的结果就是一个类型为s*的NULL指 针。如果利用这个NULL指针来访问s的成员当然是非法的,但&(((s*)0)-&m)的意图并非想存取s字段内容,而仅仅是计算当结构 体实例的首址为((s*)0)时m字段的地址。聪明的编译器根本就不生成访问m的代码,而仅仅是根据s的内存布局和结构体实例首址在编译期计算这个(常
量)地址,这样就完全避免了通过NULL指针访问内存的问题。
有人这样表达:
#define OFFSETOF(type, field) ((size_t) \
&&&&&&&&&&&&&& ((char *)&((type *)0)-&field - (char *)(type *)0))
我认为效果是一样的,多增加的那部分就是0地 址,相减后就是偏移量。
为什么要增加size_t呢?
首先size_t的定义是什么呢,在文件 stddef.h中可以找到答案。
typedef unsigned int size_t;&&&&&&&&&&&&&&&&&&&&& /*mine is 32bit machine*/
可见就是将偏移量转化为无符整型,其实32位 机器的地址就是无符号的32位整数。一般情况下,不进行size_t类型转化也是没有问题的(后面的实验可证)。我认为,只有偏移量足够大,当大于 0x时才有影响,因为这时候的偏移量最高位是1,机器默认为是负数了。似乎上面宏定义OFFSETOF中更能说明这个问题,因为这个宏定
义是一个差值,最高位是1就肯定是负数了。使用printf(&%d&, &var);打印一个变量的地址就是个负数。这只是我的看法,网上基本没有什么人分析为什么添加size_t的强制类型转化。因为系统对数组长度 的大小是有限制的,所以也不能实验得到数据。
插一句数组长度的问题(引述):
理论上来说没有限制,但是内核一般配置允许每 个进程拥有有限的内存空间,可以用系统调用函数getrlimit(int resource, struct rlimit *rlim)
获得系统的资源限制。系统的资源限制分为软件 限制和硬件限制,软件限制最大值不能超过硬件限制。数组静态获得的存储空间是分配在stack,只要知道stack的限制就知道答案了。可以使用如下代码 获得:
struct rlimit resource_
getrlimit(RLIMIT_STACK, &resource_limit);
printf(&STACK: soft_limit - %ld hard_limit - %ld\n&, resource_limit.rlim_cur, resource_limit.rlim_max);
分配大数量的数组,若是系统找不到该大小的一 段连续的存储空间,系统就会产生一个SIGSEGV信号,这时调用函数int sigaltstack(const stack_t *ss, stack_t *oss)来处理这个信号。sigaltstack储存信号SIGSEGV到一个alternate stack结构ss中,内核会先于进程运行前检查这个信号。
3.由此,到一个结构体中field所占用的字节 数就很简单了。
#define FIELD_SIZE(type, field) sizeof(((type *)0)-&field)
4.其实,系统给提供了一个相同的宏定义,在文件 stddef.h中:
在嵌入式系统里,不同开发商,不同架构处理器 和编译器都有不同的offsetof定义形式:
/* Keil 8051 */
#define offsetof(s,m) (size_t)&(((s *)0)-&m)
/* Microsoft x86 */
#define offsetof(s,m) (size_t)(unsigned long)&(((s *)0)-&m)
/* Motorola coldfire */
#define offsetof(s,memb) ((size_t)((char *)&((s *)0)-&memb-(char *)0))
/* GNU GCC 4.0.2 */
#define offsetof(TYPE, MEMBER) __builtin_offsetof (TYPE, MEMBER)
虽然定义形式不同,但功能都是返回成员在数据 结构中的偏移量,都是为了提高代码的可移植性。
offsetof虽然同样适用于union结 构,但它不能用于计算位域(bitfield)成员在数据结构中的偏移量。
typedef struct
unsigned int a:3;
unsigned int b:13;
unsigned int c:16;
使用offset(foo,a)计算a在 foo中的偏移量,编译器会报错。
6.应用(引述)
offsetof与EEPROM
我们许多人可能都使用过一些非挥发性的存储器,如常见的EEPROM。我们经常使用它们在存储一些系统的配置参数和设备信息。在所有的EEPROM中,通 串过口访问的占了大多数。一般来说,对串口的访问都是按字节进行的,这使得我们不可避免会设计出下面的接口去访问EEPROM的信息:
/*从EEPROM 偏移量offset处读取nBytes到RAM地址dest*/
ee_rd(uint16_t offset, uint16_t nBytes, uint8_t * dest);
然而,这种接口必须要知道偏移量offset 和读取字节数nBytes。可能你会采用下面的方法解决方法解决这个问题:
定义一个数据结构和一个指向这个数据结构的指 针,并初始化这个指针为EEPROM的起始地址EEPROM_BASE.
#define EEPROM_BASE 0x0000000/*配置信息的起始地址*/
typedef struct
&&&& int&&&
&&&& char&&
EEPROM * const pEE = EEPROM_BASE
ee_rd(&(pEE-&f), sizeof(pEE-&f), dest);
没错,这种方法的确可以达到访问指定地址的信 息。不过这种方法也存在下面的问题:
a.容易使代码维护人员人误以为在ee_rd 接口内部也存在EEPROM的数据结构。
b.当你编写一些自己感觉良好编译器不报错的 代码,比如pEE-&f = 3.2,你可能意想不到灾难将要来临。
c.这个接口没有很好地体现EEPROM所隐 含的硬件特性。
到这里,有人可能会想到offsetof来解 决这个问题:
#define offsetof(type, f) ((size_t) \
&&& ((char *)&((type *)0)-&f - (char *)(type *)0))
typedef struct
&&&& int&&&
&&&& char&&
ee_rd(offsetof(EEPROM,f), 4, dest);
如果让编译器来计算nBytes而不是我们自 己给出那就更好了。这时,一定有人会马上提到sizeof。可是怎么使用呢,我们不能用sizeof(EEPROM.f)来计算nBytes吧?!因为 EEPROM是数据类型,不是对象,没有办法操作f域呀。
/*类似于offsetof的定义*/
#define SIZEOF(s,m) ((size_t) sizeof(((s *)0)-&m))
ee_rd(offsetof(EEPROM, f), SIZEOF(EEPROM, f), &dest);
其实还可以精简为下面的最终形式:
#define EE_RD(M,D)&& ee_rd(offsetof(EEPROM,M), SIZEOF(EEPROM,M), D)
EE_RD(f, &dest);
,这样我们只用传递两个参数,不用再考虑 应该从那里读取数据以及读取多少的问题。
有人会说这种简化都是建立在 EEPROM_BASE为0x0000000基础之上的,可能会反问,如果配置信息不是从0地址开始的呢?
其实我们可以通过下面的方法解决。
#define EEPROM_BASE 0x00000a10
typedef struct
&&&& char&& pad[EEPROM_BASE];/*使数据结构的前EEPROM_BASE个字节填&空&*/
&&&& int&&&
&&&& char&&
使用offsetof简化EEPROM的串口 访问的确很妙。这里还有一个很好的例子。在嵌入式应用中,我们时常将一些I/O寄存器映射到内存地址空间进行访问。这种映射使原本复杂的寄存器访问变得象 访问普通的RAM地址一样方便。PowerPC 8250访问外部的ROM控制器(ROM controller)的寄存器就是通过这种方式实现的。ROM控制器所有的寄存器被映射到从I/O寄存器空间基地址
0x(IO_BASE)偏移0x60000(ROMCONOffset)字节的一段内存。每个寄存器占用四个字节,并有一个数据结构与它 们对应。比如控制ROM控制器工作状态的寄存器对应数据结构ROMCON_ROM_CONTROL,配置PCI总线A的寄存器对应数据结构 ROMCON_CONFIG_A,下面先看看这些数据结构的定义:
#define IO_BASE&&&&& 0x
#define ROMCONOffset 0x60000
typedef unsigned int NW_UINT32;
typedef struct _ROMCON_CONFIG_A {
&&& union {
&&&&&&& struct {
&&&&&&&&&&& UINT32 pad4:21;&&&&&&&& /* unused&& */
&&&&&&&&&&& UINT32 pad3:2;&&&&&&&&& /* reserved */
&&&&&&&&&&& UINT32 pad2:5;&&&&&&&&& /* unused&& */
&&&&&&&&&&& UINT32 EnablePCIA:1;
&&&&&&&&&&& UINT32 pad1:1;&&&&&&&&& /* reserved */
&&&&&&&&&&& UINT32 EnableBoot:1;&&&&&&&&
&&&&&&&&&&& UINT32 EnableCpu:1;&&&& /*bit to enable cpu*/
&&&&&&& struct {
&&&&&&&&&&& UINT32 ConfigA;
&&&&&&& } nlstruct4;
} ROMCON_CONFIG_A, *PROMCON_CONFIG_A;
typedef struct _ROMCON_ROM_CONTROL {
&&& union {
&&&&&&& struct {
&&&&&&&&&&& UINT32 TransferComplete:1;
&&&&&&&&&&& UINT32 pad3:1;&&&&&&&&&&& /* unused */
&&&&&&&&&&& UINT32 BondPad3To2:2;
&&&&&&&&&&& UINT32 Advance:3;
&&&&&&&&&&& UINT32 VersaPortDisable:1;
&&&&&&&&&&& UINT32 pad2:1;&&&&&&&&&&& /* unused */
&&&&&&&&&&& UINT32 FastClks:1;
&&&&&&&&&&& UINT32 pad1:7;&&&&&&&&&&& /* unused */
&&&&&&&&&&& UINT32 CsToFinClks:2;
&&&&&&&&&&& UINT32 OeToCsClks:2;
&&&&&&&&&&& UINT32 DataToOeClks:2;
&&&&&&&&&&& UINT32 OeToDataClks:3;
&&&&&&&&&&& UINT32 CsToOeClks:2;
&&&&&&&&&&& UINT32 AddrToCsClks:2;&&&&&&&&
&&&&&&&&&&& UINT32 AleWidth:2;
&&&&&&& struct {
&&&&&&&&&&& UINT32 RomC
&&&&&&& } nlstruct4;
} ROMCON_ROM_CONTROL, *PROMCON_ROM_CONTROL;
typedef struct
&&& ROMCON_CONFIG_A&&&& ConfigA;
&&& ROMCON_CONFIG_B&&&& ConfigB;
&&& ROMCON_ROM_CONTROL RomC
}ROMCON, *PROMCON;
---------------------------- &-IO_BASE:0x&&&
|&& |&& |&& |&& |&& |&& |...
----------------------------&&&&&&&&
|&& |&& |&& |&& |&& |&& |...
---------------------------- &-ROMCONOffset(ROMCON):0x60000&&&&&
|&& |&& |&& |&& |&& |&& |...
---------------------------- &-ROMCON_ROM_CONTROL&&&&&&&&&&&&
----------------------------
那么如何访问 ROMCON_ROM_CONTROL对应寄存器呢,比如ROMCON_ROM_CONTROL对应寄存器的VersaPortDisable位?
估计有人可能会这样做:
事先定义成员 RomControl(ROMCON中用ROMCON_ROM_CONTROL定义的实例)相对于ROMCON的偏移量,
#define ROMCONRomControlOffset 0x8
然后设计访问ROM的接口如下:
/*读取ROM控制器位于src位置的寄存器 数据到dest*/
typedef unsigned long dword_t;
void rom_read(dword_t* src, uint32_t* dest);
void rom_write(dword_t* src, uint32_t* dest);
最后利用这个偏移量做下面的操作:
ROMCON_ROM_CONTROL tRomCtrl={0};
dword_t* pReg=(dword_t*)(IO_BASE+ROMCONOffset+ROMCONRomControlOffset);
rom_read(pReg,(uint32_t)*(&tRomCtrl));
/*查看寄存器的 VersaPortDisable位,如果该位没有启用就启用它*/
if(!tRomCtrl.nlunion.nlstruct.VersaPortDisable)
tRomCtrl.nlunion.nlstruct.VersaPortDisable = 1;
rom_write(pReg,(uint32_t)*(&tRomCtrl));
这样做确实可以达到访问相应寄存器的目的。但 是,如果和ROM相关的寄存器很多,那么定义、记忆和管理那么多偏移量不是很不方便吗?到这里,如果你对前面关于offsetof还有印象的话,我想你可 能会作下面的优化:
#define ROMCON_ADDR(m)&& (((size_t)IO_BASE+\
&&&&&&&&&&&&&&&&&&&&&&&& (size_t)ROMCONOffset+\
&&&&&&&&&&&&&&&&&&&&&&&& (size_t)offsetof(ROMCON,m))
ROMCON_ROM_CONTROL tRomCtrl={0};
dword_t* pReg=(dword_t*)ROMCON_ADDR(ConfigA);
rom_read(pReg,(uint32_t)*(&tRomCtrl));
/*查看寄存器的 VersaPortDisable位,如果没有启动就启动它*/
if(!tRomCtrl.nlunion.nlstruct.VersaPortDisable)
tRomCtrl.nlunion.nlstruct.VersaPortDisable = 1;
rom_write(pReg,(uint32_t)*(&tRomCtrl));
#include &stdio.h&
#define OFFSET(s, m)&&& &&& ((size_t)&(((s *)0)-&m))
#define OFFset(s, m)&&& &&& (&(((s *)0)-&m))
typedef struct node
&&& unsigned int cc[5];
&&& unsigned char dd[8];
typedef struct node2
&&& unsigned char cc[8];
&&& unsigned int gg[5];
int main(int argc, char * argv[])
&&& printf(&OFFSET of aa=%d\n&, OFFSET(nn, aa));
&&& printf(&OFFSET of bb=%d\n&, OFFSET(nn, bb));
&&& printf(&OFFSET of cc=%d\n&, OFFSET(nn, cc));
&&& printf(&OFFset=%d\n&, OFFset(nn, cc));
&&& printf(&OFFSET of dd=%d\n&, OFFSET(nn, dd));
&&& printf(&OFFSET of ee=%d\n&, OFFSET(nn, ee));
&&& printf(&OFFSET of ff=%d\n&, OFFSET(nn, ff));
&&& printf(&OFFSET of gg=%d\n&, OFFSET(nn, gg));
&&& printf(&OFFSET of hh=%d\n\n&, OFFSET(nn, hh));
&&& printf(&OFFSET of aa=%d\n&, OFFSET(mm, aa));
&&& printf(&OFFSET of bb=%d\n&, OFFSET(mm, bb));
&&& printf(&OFFSET of cc=%d\n&, OFFSET(mm, cc));
&&& printf(&OFFset=%d\n&, OFFset(mm, cc));
&&& printf(&OFFSET of dd=%d\n&, OFFSET(mm, dd));
&&& printf(&OFFSET of ee=%d\n&, OFFSET(mm, ee));
&&& printf(&OFFSET of ff=%d\n&, OFFSET(mm, ff));
&&& printf(&OFFSET of gg=%d\n&, OFFSET(mm, gg));
&&& printf(&OFFSET of hh=%d\n\n&, OFFSET(mm, hh));
&&& return 0;
通过GCC编译、运行后,答案简略为:
0 4 8(8) 28 36 40 44 48
0 1 2(2) 12 16 20 24 44
在32位机器中,long(long int)型数据占32bit,和short一样。long long是为了支持64位数据而产生的,表示64bit的数据。
在64位机器中,long型数据占 64bit,short占32bit。
编译器要求对齐,造成了结构体“空洞”。所以 相同类型的数据还是靠近吧。空洞问题也可以解释为什么结构体不支持比较(支持==),“空洞”中的随机数据会导致失败。
附(摘录):
1. 字节对齐(byte alignment):
现代计算机中内存空间都是按照byte划分 的,从理论上讲对于任何类型的变量的访问都可以从任何地址开始。但是实际情况是在访问特定类型变量的时候经常在特定的内存地址访问,这就需要各种类型数据 按照一定的规则在空间上排列,而不是顺序的一个接一个的牌坊,这就是对齐。
2. 对齐原因:
(1)有些CPU访问没有对齐的变量时候会发 生错误。比如Motorola 68000不允许将16位的字存储到奇数地址中, 将一个16位的字写到奇数地址将引发异常。
(2)不对数据进行对齐,会在存取效率上带来 损失。比如:有些CPU从偶数地址存储int数据,读取时需要一个机器周期,从偶数地址存储,就需要2个机器周期。
3.对齐规则:
实际上, 对于c中的字节组织, 有这样的对齐规则:&&&
(1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除;
(2) 结构体每个成员相对于结构首地址的偏移量(offset)都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节(internal adding);
(3) 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节(trailing padding)。
不同CPU的对其规则可能不同, 请参考手册。为什么会有上述的限制呢? 理解了内存组织, 就会清楚了。
CPU通过地址总线来存取内存中的数据,32 位的CPU的地址总线宽度既为32位置, 标为A[0:31]。在一个总线周期内,CPU从内存读/写32位。 但是CPU只能在能够被4整除的地址进行内存访问,这是因为: 32位CPU不使用地址总线的A1和A2(比如ARM,它的A[0:1]用于字节选择, 用于逻辑控制, 而不和存储器相连,存储器连接到A[2:31])。访问内存的最小单位是字节(byte),
A0和A1不使用, 那么对于地址来说, 最低两位是无效的,所以它只能识别能被4整除的地址了。 在4字节中,通过A0和A1确定某一个字节。
4. 字节对齐对程序的影响:
(32bit、x86、gcc)(所占字节数 char:1, short:2, int:4, long:4, float:4, double:8)
sizeof(strcut A) == 8
sizeof(struct B) == 12
5.修改默认对齐:
(1)编程时,使用#pragma pack()。
#pragma pack (2)&&&&&&&&&&&&&&&&&&&&&&&&& /*指定按2字节对齐*/
#pragma pack ()&&&&&&&&&&&&&&&&&&&&&&&&&& /*取消指定对齐,恢复缺省对齐*/
sizeof(strcut C) == 8 == 2(b) + 4(a) + 2(c)
(2)修改编译器的默认对齐方式。
6.编程注意情况:
(1)为了字节对齐,显示声明冗余变量。当 然,不冗余声明,编译器也会自动对齐。
&&& char reserved[3]; && &&&&&&&&&&&& /*使用空间换时间*/
(2)带来隐患,尤其是对代码移植的影响。
unsigned int i = 0x;
unsigned char *p=NULL;
unsigned short *p1=NULL;
p1=(unsigned short *)(p+1);
*p1=0x0000;
最后两句代码,从奇数边界去访问 unsigned short型变量,显然不符合对齐的规定。
在x86上,类似的操作只会影响效率,但是在 MIPS或者sparc上,可能就是一个error,因为它们要求必须字节对齐。
更多相关文章
宏定义:得到一个field在结构体(struct type)中的偏移量 #define OFFSETOF(type, field) ((size_t)&(((type *)0)-&field)) (type *)0:把0地址当成type类型的指针. ((type *)0)-&fi ...
#define OFFSETOF(type, field) ((size_t)&(((type *)0)-&field))(type *)0:把0地址当成type类型的指针.((type *)0)-&field:对应域的变量.&((type *)0)-&field ...
[了解]10-函数指针概念及定义 函数指针变量 存放函数的首地址的指针变量就是函数指针变量 函数指针变量的定义 返回值类型 (*变量名)(函数的参数); 函数的声明: int sum(int a,int b);-& 函数指针 int (*p1)(int a,int b); //定义了一个函数指 ...
定义结构体变量 /* 结构体 自定义的一种类型称为构造类型,在C语言中称为结构体 定义结构体: struct [结构体名] { [成员列表;] }; 定义结构体变量 1.struct 结构体名 变量名; { } 引用结构体成员 (运算符.) 结构体变量.成员 定义结构体变量并初始化 struct 结 ...
field在结构体(struct)中的偏移量 1 #include &stdio.h&
2 /*get the offset of field*/
3 #define FPOS(type,field) ((dword)&((type *)0)-& ...
题目:用一个宏定义FIND求一个结构体struct里某个变量相对struc的编移量如:struct student { } 则: FIND(struct student,a); //等于0 FIND(struct student,b);//等于4答案 ...
C语言中宏定义的一个变态用法 在程序调试时,我们经常需要输出一些调试信息,当调试完毕后,就不再需要使用了.那怎么快速的在调试状态和发布状态切换呢?通常我们使用预编译加宏定义来处理这个问题,例如:#ifdef DEBUG调试代码#endif如果我们使用printf来显示一些调试信息,那么每个地方都加上 ...
用一个宏求结构体某个变量的相对偏移量 如: stuct student
char b[20];
} 则: FIND(student,a); //等于0 FIND(student,b);//等于4 #defineFIND( struc, e )
还记得6月2号,我们小组集体开了一个英语的小会.主要涉及到6月英语计划的问题. 当初定的旧 ...
最近遇到这样一个问题:将一个窗口句柄以参数的形式传递给一个线程,在线程中使用完之后要将窗口销毁,调用DestroyWindow销毁窗口是返回false,GetLastError的结果为5:拒绝访问,而在线程外则是可以 ...
来源:/developerworks/cn/web/1 ...
常见的一个场景是Hive里面一个带分区的表,原来是int类型的字段,后来发现数据超过了int的最大值,要改成bigint.或者是 bigint要改string或decimal.无论如何,对于带分区的表,要改列类型,有 ...
昨天,我写了如何通过我们的巴斯发送通知(后端即服务)在Delphi XE6支持在iOS和Android移动设备博客文章.本博客文章假定您遵循我以前的博客文章,并在引用docwiki文章中的步骤. 在这篇文章中,我想我 ...
1.XMLHTTPRequest Ajax的一个最大的特点是无需刷新页面便可向服务器传输或 ...
今天是我来到云和学院正式开班上课的第一天,我选择学习的科目是.net.因为.net我在学校的时候接触过一些,所以我想要更加深入的去学习.我觉得一个学生在学习上最怕的是没有遇到一位负责任的好老师,但幸运的是 ...
//栈的链式储存(不存在上溢) #include&malloc.h& #include&stdio.h& typedef char ElemT struct linknode { El ...
最近抽空,写了一份关于&Red Hat Enterprise Linux5系统Sendmail配置&文档,配置的目标:通过配置SendMail服务实现本地用户可以自由发送和接收邮件,并且,可以对外网特定的 ...
/******************************************** 实验名称:Led发光管实验一 实验目的:用位操作和总线操作点亮第一个发光管 ************************ ...

我要回帖

更多关于 struct 重定义 的文章

 

随机推荐