unreal3之FName及潜在bug
FName是unreal3里对字符串高效处理的一种机制
基本原理就是把字符串hash存起来,然后每个字符串就只需要用一个数组索引值来表示了
FName的属性:
NAME_INDEX Index;
INT Number;
Index就是数组索引,Number是一种特殊用途:系统在生成对象时通常会规律自动起名,如Object_12、Object_13、Object_14等等,若每一个都单独保存就很浪费,FName会把它末尾的数字拆开,只对前半节做hash保存,这样三个名字得到的Index值都一样了,而不一样的数字部分则存在Number里。
FName的实例属性也就这两个,其它都是静态成员了,就是数组和hash表:
/** Table of all names. This is a NoInit because we may need to use it before the constructor is called due to random static variable initialization order */
static TArrayNoInit<FNameEntry*> Names;
/** Name hash. */
static FNameEntry* NameHash[ FNameDefs::NameHashBucketCount ];
其中Names就是所有FName按先来后到顺序存放的数组,当要从一个FName获取其FString时,就是通过Names[Index]->AnsiName来访问了
而NameHash则是用来快速查找的hash表,其索引就是各字符串的hash值。
然而这个hash值的计算是忽略大小写的,这就导致一个大问题:
FName居然是不区分大小的!
就算UnrealEngine内部自己约定,所有名字变量都不区分大小写,也仍然有问题,因为,C++语言本身是区分大小写的!
我就碰到过一个这样的bug:
当重新编译脚本并生成C++头文件时,FURL里有一个字段Host,在脚本定义时明明是大写,可是一生成C++代码就成了小写,按理说这是相当基础的内部类,我根本就不可能改到它,为什么它会自己变样呢?如果我尝试把它名字改成Host2之类的,它就不会变小写了。
经过一连串的跟踪,终于在调试器的帮助下找到了原因:因为在解析uc文件里的每一句变量声明时,都会用一个FName来保存读到的变量名,而如果这串字符之前已经有遇到过,那么无论其大小写是否一样,都会认为是同一个值并使用之前已经存储的版本,而此次的真实值就被抛弃了。恰好我在INI文件里定义了一个host=XXXX的属性对,由于加载INI在前,解析脚本类在后,所以当解析到FURL结构里的Host字段时,发现FName::Names里已经有了一个小写的host项,就直接把它当作变量名使用了!然而C++编译器可是区分大小写的,原来代码里那么使用Host的地方,在小写的新版头文件下,肯定编译出错。
解决的办法,当然只能是去修改INI里的Key了,然而这真的是一个非常隐蔽的BUG啊,哪天又一不小心重名了,分分钟跳坑。。。
unreal3之FName及潜在bug的更多相关文章
- Session 潜在bug防范
注意: Session的使用一定要及时的清理,因为它是“全局”的(包括其生命周期),所以在使用Session保存状态时,不用时要及时的NULL掉,小心潜在的Bug.
- Java-idea-FindBugs字节码级别潜在bug查看
一.概述 静态分析工具承诺无需开发人员费劲就能找出代码中已有的缺陷. FindBugs 不注重样式或者格式,它试图只寻找真正的缺陷或者潜在的性能问题. FindBugs 是一个静态分析工具,它检查类或 ...
- Java-idea-PMD源文件级别潜在bug查看
一.概述 PMD(Project Manager Design)是一种开源分析Java代码错误的工具.与其他分析工具不同的是,PMD通过静态分析获知代码错误.也就是说,在不运行Java程序的情况下报告 ...
- 检测代码潜在bug和质量之SonarQube
参数使用 项目分析参数可以在多个地方设置,继承关系如下: 全局分析参数,通过Web UI设置,作用于所有项目(配置–>通用–>通用中设置) 项目分析参数,通过WebUI设置,覆盖全局参数( ...
- 添加PMD插件扫描潜在的bug
上一节使用checkstyle来规范你的项目主要解决了代码编码规范问题,比如缩进换行等.这次继续代码健康工具类PMD. 什么是PMD PMD真的不像checkstyle这样的东西所见即所得啊,去官网找 ...
- Erlang 程序引发共享内存 bug 的一个例子
虽然 Erlang 的广告说得非常好,functional.share-nothing.消息传递,blah blah 的,好像用 Erlang 写并发程序就高枕无忧了,但是由于 Erlang 信奉高度 ...
- 实际例子描述和分析“猎豹抢票跨站推荐功能有票刷不到”的疑似bug
前言 快过年了,又到了一年抢票时.今年douba和douma计划要带着doudou回姥姥家.昨天在家用抢票软件居然发现了一个bug,那就是在猎豹抢票中跨站推荐的车票几天里一直是没有,但是在12306手 ...
- 关于C/C++语言的部分BUG
目录 scanf格式匹配引发的错误 局部变量被释放引发的bug 数组写入超出索引维度 指针的指针引发的思考 未定义赋值的变量引发的bug 题外话 scanf格式匹配引发的错误 运行如下程序时,出现 ...
- UVa 658 - It's not a Bug, it's a Feature!(Dijkstra + 隐式图搜索)
链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...
随机推荐
- SQL Server 2012将数据库备份到网络中的共享文件夹
把计算机computer1 中的数据库备份到计算机computer2(IP:192.168.0.130)中的一个共享文件夹下 在computer2中的F盘下建一个共享文件夹叫DBBackupShare ...
- ADF_Data Binding系列1_使用Bean Data Control
2015-02-16 Created By BaoXinjian
- NHibernate和 FluentNHibernate
NHibernate有两类配置文件,一个是数据库连接配置文件(一般写到程序配置文件里),另一个是数据表和实体的映射文件(实体类.hbm.xml) 开源的框架Fluent NHibernate,有了它, ...
- springmvc视图解析流程
无论目标方法返回String.VIew或者是ModelAndView,springmvc都会转化成ModelAndView 然后通过视图解析器(如InternalResouceViewResolver ...
- Visual Studio Enterprise 2015下载 Update3
Visual Studio 2015 是一个丰富的集成开发环境,可用于创建出色的 Windows.Android 和 iOS 应用程序以及新式 Web 应用程序和云服务. 1.适用于各种规模和复杂程度 ...
- IRaster、IRasterlayer、IRasterdataset之间的转换
IRaster.IRasterlayer.IRasterdataset之间的转换 layer = axMapControl.get_Layer(0);//需要的栅格图层 IRasterLayer ra ...
- 【转】JVM内存模型
http://longdick.iteye.com/blog/473866 图解JVM内存模型 博客分类: JVM JVM活动SUN /** * 转载请注明作者longdick http:/ ...
- DELPHI声明一个指针变量,什么时候需要分配内存,什么时候不需要分配内存?
DELPHI声明一个指针变量,什么时候需要分配内存,什么时候不需要分配内存?比如我定义个变量 var p:Pchar;如果这个变量声明为全局变量,需要分配内存吗?分配为局部变量,需要分为内存吗?为什么 ...
- '<', hexadecimal value 0x3C, is an invalid 问题解决
你的web.config 里面一定有个节点的不完整,如 错误如下: 正确的如下:
- springMVC下载FTP上的文件
springMVC下载FTP上的文件 今天没时间写.先上传 一个工具类 工具类 package com.utils; import java.io.File; import java.io.FileO ...