S内联函数的好处与不足运行出现参数不足是不是就无法运行?求大神帮帮

>>>>运行时错误-3061,参数不足,期待是1
运行时错误-3061,参数不足,期待是1 0:0:0 用友U8编辑
运行时错误-3061,参数不足,期待是1运行时错误:3061,参数不足,期待是1
版本:U810.0 问题现象:凭证打印提示:运行时错误:3061,参数不足,期待是1. 解决方法:把总账--&设置--&选项--&账簿中的有个选项“打印时按客户端保存”的勾去掉
如果您的问题还没有解决,可以到 上找一下答案
找不到序列号315无法定位于INTERNET.DLL上 找不到序列号315无法定位于INTERNET.DLL上找不到序列号315无法定位于INTERNET.DLL上
建议你用360系统急救箱急救一下,急救后用它恢复一下系统文件和DLL文件,重启电脑看看能否正常,注意用急救箱必须在联网的状态下运行。下载个“360系统急救箱”,已经安装了“360安全卫士”的朋友,直接打开“查杀木马”,“自定义扫描”的下面的“360系统急救箱”,点击它:【1】。开始急救!急救完毕后,立即处理,重启!【2】。开机后,“文件恢复区”,彻底删除文件!【3】。“系统修复”,全选,立即修复!【关键】【4】。网络修复,开始修复,重启电脑!【关键】【5】。dll文件恢复,扫描一下,如果有丢失,添加恢复,没有就行了!
用友T3普及版10.6plus1 数据升级 T3标准版10.9 报错 如图 请问怎么解决 用友T3普及版10.6plus1 数据升级 T3标准版10.9 报错 如图 请问怎么解决
这个可以使用工具处理一下,工具名称:T3升级问题工具之降级处理,请在服务社区-更多-工具下载中进行下载http://service.chanjet.com/main/supportgongju;先备份账套,然后使用工具,再登录系统管理中升级sql server数据;如果工具处理完还不能成功升级,就需要进一步查看数据进行处理了,请在支持网上提交数据问题,由我们进一步处理!@服务社区刘明新: 谢谢,您好 我按照您给的方法操作,账套可以选择,但是提示没有可供选择的年度@张UJV:选择一个其他账套,看有年度么@服务社区刘明新:
演示账套有年度@张UJV:这个数据有异常,请联系代理商在支持网上提交数据问题,由我们进一步处理一@服务社区刘明新: 谢谢 我把 图片数据库中的accinformation表中的csysid='aa' and cid=99中 的版本号 8.21906
在升级 就没有报错,请问这对已有使用有什么影响么
只有总账 跟报表模块@张UJV:没有影响,正常了@服务社区刘明新: 好的 谢谢 对以后没影响就行@张UJV:[/微笑]
对应版本:用友U8.52对应产品线:供应链对应模块:销售管理模块问题现象:设置存货自由项1为”货物或折扣”,并在销售统计表的格式设计中加入过滤条件”货物或折扣”,在查询时如果输入自由项1的值,则什么也查不出(一直在读取数据源,无任何结果显示).演示帐套999中也是如此问题原因:同解决方案解决方案:请执行,U851销售统计表(A,852).sql
对应版本:用友U8.52对应产品线:财务系统对应模块:总账模块问题现象:本月月末自动结转凭证少结转数据问题原因:本月新添加过损益类科目但在相应的转帐定义中没有做改动,所以少结转,修改后即可解决方案:本月新添加过损益类科目但在相应的转帐定义中没有做改动,所以少结转,修改后即可
用友U8 在应付帐款中查询业务明细帐的时候:发现采购入库单也反映在上面,导致应付帐款虚增一倍用友U8 在应付帐款中查询业务明细帐的时候:发现采购入库单也反映在上面,导致应付帐款虚增一倍
问题原因:同解决方案
解决方法:过滤界面选择不包含采购入库单即可
用友U8年结后是否可以增加期初销售发货单?--用友U8年结后是否可以增加期初销售发货单?用友U8年结后是否可以增加期初销售发货单?">用友U8年结后是否可以增加期初销售发货单?
用友u8软件退出发货单在进入发货单时,刚审核的发货单自动弃审退出发货单在进入发货单时,刚审核的发货单自动弃审
退出发货单在进入发货单时,刚审核的发货单自动弃审原因分析:用户自定义发货单主表(dispatchlist)的触发器问题解答:建议用户删除该触发器,因自定义触发器有可能对后续业务,包括年结和升级产生影响。其业务需求使用其他变通方法实现,比如使用远程号来传递分子公司的单据。如果一定要使用触发器,则请仔细检查该触发器的内容,确保无误。
用友u8软件销售出库单界面能不能设置操作员看不到最近进价?销售出库单界面能不能设置操作员看不到最近进价?
销售出库单界面能不能设置操作员看不到最近进价?原因分析:可以对该操作员进行相关权限设置。问题解答:维护中心-用户权限-用户组权限-其它-查看成本权限,将该权限去掉则在参照商品信息的时候最近进价就会以*代替显示。
对应版本:用友U8.51对应产品线:公共平台对应模块:系统管理模块问题现象:安装软件提示不支持接口问题原因:环境问题解决方案:安装directx9.0
对应版本:用友U8.51A对应产品线:供应链对应模块:存货核算模块问题现象:存货模块安装完后提示控件错误,重装也没用问题原因:权限不足,无法对部分目录内的DLL文件或OCX文件进行注册,导致运行时报错解决方案:要求网管给予权限
用友u8v12.0最新报价用友u8v12.0最新报价:QQ
财务会计 1-及以上站点: ([点数]-1)*6000元
总账 13000元
应收管理 7800元
应付管理 7800元
固定资产 7000元
UFO报表 5600元
费用预算 30000元
网上银行 20000元
出纳管理 5000元
医药费用管理 59800元
网上报销 1-及以上站点: ([点数]-1)*元
管理会计 1-及以上站点: ([点数]-1)*23000元 资金管理 62800元
成本管理 69000元
标准成本 42800元
项目成本 48800元
成本分项管理 49800元
预算管理-企 1-及以上站点: ([点数]-1)*元
供应链 1-及以上站点: ([点数]-1)*11000元 采购管理 16800元
销售管理 16800元
库存管理 16800元
存货核算 16800元
合同管理 32000元
售前分析 25800元
质量管理 32000元
委外管理 26800元
GSP质量管理 42800元
进口管理 29800元
出口管理 29800元
VMI管理 34800元
序列号 15800元
部门用料计划 35800元
进程管理 45000元
服装行业样品管理 49800元
服装行业销售业务 62000元
服装行业采购委外业务 18000元
服装行业库存业务 46000元
按质计价 49800元
质量管理-流程 58000元
售后服务 35800元
品控报表 12800元
采购询报价管理 11800元
借用归还 12800元
农户收购 62800元
运输管理 58000元
寄售 29800元
服装行业二维表单 9600元
电商订单中心 69600元
库存条码—PC版 42800元
库存条码-无线版 1-及以上站点: ([点数]-1)*元
GMP基础应用 42800元
会员管理 39800元
生产制造 1-及以上站点: ([点数]-1)*21600元 物料清单 36000元
主生产计划 47800元
需求规划 47800元
产能管理 47800元
生产订单 47800元
车间管理 62800元
设备管理 48800元
工程变更管理 48800元
工序委外管理 35800元
服装行业车间管理 56000元
服装行业生产计划通知 86000元
服装行业计件工资 38000元
有限排产 200000元
有限排产模具算法 100000元
模具管理 79800元
生产用料分摊 32800元
物料重计 39800元
LED分光分选 39800元
生产线日计划 29800元
GMP管理 150000元
人力资源 1-及以上站点: ([点数]-1)*9600元 人事管理 12800元
人事合同管理 12800元
薪资管理 12800元
计件工资 22000元
集体计件 22000元
保险福利管理 13800元
考勤休假管理 43800元
招聘管理 22000元
培训管理 22000元
员工自助 1-30站点: 22000元
31-及以上站点: ([点数]-30)*500+22000元
经理自助 1-10站点: 20000元
11-及以上站点: ([点数]-10)*800+20000元
绩效管理 1-及以上站点: ([点数]-1)*元
集团管理 1-及以上站点: ([点数]-1)*21000元 集团财务 56000元
合并报表 56000元
结算中心 56000元
预算管理-集 90000元
网上结算 1-及以上站点: ([点数]-1)*元
内部审计 1-及以上站点: ([点数]-1)*元
CRM营销管理 1-及以上站点: ([点数]-1)*元
CRM服务管理 1-及以上站点: ([点数]-1)*元
呼叫中心-坐席端 1-及以上站点: ([点数]-1)*元
呼叫中心集成 0元
PDM-Professional7.x 1-760站点: 0元
PDM包 5-及以上站点: ([点数]-1)*13000元
基础功能包 30000元
文档管理 20000元
零部件管理 20000元
产品结构管理 30000元
变更管理 40000元
PLM项目管理 60000元
产品工艺管理 60000元
军工行业插件 150000元
AutoCAD集成 1-及以上站点: ([点数]-1)*元
CAXA集成 1-及以上站点: ([点数]-1)*元
SolidWorks集成 1-及以上站点: ([点数]-1)*元
CATIA集成 1-及以上站点: ([点数]-1)*元
SolidEdge集成 1-及以上站点: ([点数]-1)*元
Pro/E集成 1-及以上站点: ([点数]-1)*元
UG集成 1-及以上站点: ([点数]-1)*元
Inventor集成 1-及以上站点: ([点数]-1)*元
Protel集成 1-及以上站点: ([点数]-1)*元
PADS集成 1-及以上站点: ([点数]-1)*元
Project集成 1-及以上站点: [点数]*元
CAD集成平台 30000元
用友erp软件报价表用友erp软件报价表:QQ
财务会计 1-及以上站点: ([点数]-1)*6000元
总账 13000元
应收管理 7800元
应付管理 7800元
固定资产 7000元
UFO报表 5600元
费用预算 30000元
网上银行 20000元
出纳管理 5000元
医药费用管理 59800元
网上报销 1-及以上站点: ([点数]-1)*元
管理会计 1-及以上站点: ([点数]-1)*23000元 资金管理 62800元
成本管理 69000元
标准成本 42800元
项目成本 48800元
成本分项管理 49800元
预算管理-企 1-及以上站点: ([点数]-1)*元
供应链 1-及以上站点: ([点数]-1)*11000元 采购管理 16800元
销售管理 16800元
库存管理 16800元
存货核算 16800元
合同管理 32000元
售前分析 25800元
质量管理 32000元
委外管理 26800元
GSP质量管理 42800元
进口管理 29800元
出口管理 29800元
VMI管理 34800元
序列号 15800元
部门用料计划 35800元
进程管理 45000元
服装行业样品管理 49800元
服装行业销售业务 62000元
服装行业采购委外业务 18000元
服装行业库存业务 46000元
按质计价 49800元
质量管理-流程 58000元
售后服务 35800元
品控报表 12800元
采购询报价管理 11800元
借用归还 12800元
农户收购 62800元
运输管理 58000元
寄售 29800元
服装行业二维表单 9600元
电商订单中心 69600元
库存条码—PC版 42800元
库存条码-无线版 1-及以上站点: ([点数]-1)*元
GMP基础应用 42800元
会员管理 39800元
生产制造 1-及以上站点: ([点数]-1)*21600元 物料清单 36000元
主生产计划 47800元
需求规划 47800元
产能管理 47800元
生产订单 47800元
车间管理 62800元
设备管理 48800元
工程变更管理 48800元
工序委外管理 35800元
服装行业车间管理 56000元
服装行业生产计划通知 86000元
服装行业计件工资 38000元
有限排产 200000元
有限排产模具算法 100000元
模具管理 79800元
生产用料分摊 32800元
物料重计 39800元
LED分光分选 39800元
生产线日计划 29800元
GMP管理 150000元
人力资源 1-及以上站点: ([点数]-1)*9600元 人事管理 12800元
人事合同管理 12800元
薪资管理 12800元
计件工资 22000元
集体计件 22000元
保险福利管理 13800元
考勤休假管理 43800元
招聘管理 22000元
培训管理 22000元
员工自助 1-30站点: 22000元
31-及以上站点: ([点数]-30)*500+22000元
经理自助 1-10站点: 20000元
11-及以上站点: ([点数]-10)*800+20000元
绩效管理 1-及以上站点: ([点数]-1)*元
集团管理 1-及以上站点: ([点数]-1)*21000元 集团财务 56000元
合并报表 56000元
结算中心 56000元
预算管理-集 90000元
网上结算 1-及以上站点: ([点数]-1)*元
内部审计 1-及以上站点: ([点数]-1)*元
CRM营销管理 1-及以上站点: ([点数]-1)*元
CRM服务管理 1-及以上站点: ([点数]-1)*元
呼叫中心-坐席端 1-及以上站点: ([点数]-1)*元
呼叫中心集成 0元
PDM-Professional7.x 1-760站点: 0元
PDM包 5-及以上站点: ([点数]-1)*13000元
基础功能包 30000元
文档管理 20000元
零部件管理 20000元
产品结构管理 30000元
变更管理 40000元
PLM项目管理 60000元
产品工艺管理 60000元
军工行业插件 150000元
AutoCAD集成 1-及以上站点: ([点数]-1)*元
CAXA集成 1-及以上站点: ([点数]-1)*元
SolidWorks集成 1-及以上站点: ([点数]-1)*元
CATIA集成 1-及以上站点: ([点数]-1)*元
SolidEdge集成 1-及以上站点: ([点数]-1)*元
Pro/E集成 1-及以上站点: ([点数]-1)*元
UG集成 1-及以上站点: ([点数]-1)*元
Inventor集成 1-及以上站点: ([点数]-1)*元
Protel集成 1-及以上站点: ([点数]-1)*元
PADS集成 1-及以上站点: ([点数]-1)*元
Project集成 1-及以上站点: [点数]*元
CAD集成平台 30000元
对应版本:用友U8.50对应产品线:财务系统对应模块:总账模块问题现象:凭证打印时出现打印设置无效、错误107问题原因:凭证打印时出现打印设置无效可能的情况之一PRNITEX表出错,要将PRINTEX表从演示帐套中导入,107错误发现客户将凭证打印的行数改为8行,而自定义纸张的大小设为5行,解决方案:凭证打印时出现打印设置无效可能的情况之一PRNITEX表出错,要将PRINTEX表从演示帐套中导入,107错误发现客户将凭证打印的行数改为8行,而自定义纸张的大小设为5行,要把选项口的行数改为5行
对应版本:用友U8.51对应产品线:财务系统对应模块:总账模块问题现象:调凭证打印用自定义纸张的设置不能保存问题原因:打印机参数设置问题解决方案:在打印机设置里的打印首选项的参数设置为自定义纸张的参数即可
T6 5.1的版本,只启用了库存管理和存货核算模块,那么采购入库单怎么能实现批量审核呢,一张张审核实在太慢了,还有个问题,就是是不是不用审核就可以月结呢,看了下客户那边的数据,都是已经全部月结过的数据。难道可以不用审核就可以月结了吗?麻烦解答下,谢谢。 T6 5.1的版本,只启用了库存管理和存货核算模块,那么采购入库单怎么能实现批量审核呢,一张张审核实在太慢了,还有个问题,就是是不是不用审核就可以月结呢,看了下客户那边的数据,都是已经全部月结过的数据。难道可以不用审核就可以月结了吗?麻烦解答下,谢谢。[]
您好!您在入库单列表中选择您要审核的入库单,或者全选都可以批量审核。库存模块确实可以不审核结账@畅捷服务张彩用 :但是在月结的时候,却提示有未审核的单据,但是我发现1-11月份的单据都是没有审核的,为什么12月会提示呢,我现在已经建好了2016年的年度账,结转数据的时候提示这个。@周军nYN:年度结转前需要都审核完成上年的单据。
用友票据通存支票打印进账单用友票据通存支票打印进账单
用友票据通存支票打印进账单
存支票打印进账单,是指本企业在收到支票后将其存入银行并打印进账单。1. 设置账户。使用进账单自动记账时,首先要在账户管理中预设一账户并启用。此启用的账户中的“银行账号”、“开户行”、“公司名称”是进账单的收款人部分内容。 此银行账号为进账单收款人账号,此项为必填项。预设账户请参照账户管理部分。2. 设置票据属性。请打开一张要套打的票据,例,华夏银行进账单,进入其【设计票据】模板界面,双击票据空白处设置其票据属性。选择允许记账并选择当前票据类型,例,进 账单。3. 填写票据内容。选择一张要打印的进账单,填入其内容,收款人部分内容请与第一步预设的账户内容相同 。进账单自动记账的前提是“收款人账号”必须与账户下的“银行账号”一致。4. 自动记账。点击打印,会自动弹出“日记账登记”窗口,其“账户名称”、“日期”、“结算方式”、以及进账单的金额均会自动记上, 此时可填入剩余信息,编辑完成点击确定即可把进账单的信息登记在日记账中。
录销售退货单时,提示这个,什么原因? 录销售退货单时,提示这个,什么原因?
磁盘空间看看是不是满了简版数据库文件大小限制2g,升级一下数据库版本
出报表提示请先安装cell插件 出报表提示请先安装cell插件[]
12.0的版本需要打上产品补丁,再登录界面点击浏览器设置,下载浏览器设置工具自动检测修复。下载安装即可@董江川:无下载方式啊打开打印凭证-打印模版设置-提示下载-安装即可@董江川:[/强]
单据在单据查询中可以看到,但是在单据处理--单据审核中却找不到_标题:单据在单据查询中可以看到,但是在单据处理--单据审核中却找不到问题解答:该单据已经被核销,如果该单据需要进行修改或删除。需要在其他处理--取消操作--核销中进行处理即可
对应版本:用友U其他对应产品线:供应链对应模块:库存管理模块问题现象:权限设置成有仓库权限,仓库权限控制,但在库存管理中依然可以做其它仓库的业务问题原因:库存管理选现是否检查仓库权限解决方案:设置检查仓库权限
用友软件U8的常用摘要如何设置用友软件(U8)的常用摘要问题,如何设置点填制凭证-点摘要栏-点摘要栏右下角的小按键会出现“常用摘要”对话框,在这里能设置常用摘要会计主管的ID肯定能设置
对应版本:用友U其他对应产品线:其他对应模块:其他模块问题现象:安装数据库时提示:以前的某个程序安装以在安装的计算机上创建挂起操作,安装程序之前必须先重起计算机。无论怎么重启计算机,一直弹出这个对话框。问题原因:注册表的有写入,删除就好。解决方案:打开注册表KEY_LOCAL_MACHINE--SYSTEM--ControlSet001--Control--SessionManager--PendingFileRenameOptions--把这个键值删除
1、2、3、4、5、6、7、8、9、10、
用友U8软件打印凭证时如何将一张凭证上同个科目的多条分录合并起来打印?打印凭证时如何将一张凭证上同个科目的多条分录合并起来打印?打印凭证时如何将一张凭证上同个科目的多条分录合并起来打印?原因分析:凭证合并打印显示功能;问题解答:勾选总账模块“设置”——“选项”——“凭证”页签里将“合并凭证显示、打印”选项勾选上,再根据实际需要的效果选择“按科目、摘要相同方式合并”或“按科目相同方式合并”的选项即可;
如何建立一个新帐套,建帐后又如何把目前使用的帐套的数据全部引入问题描述:如何建立一个新帐套,建帐后又如何把目前使用的帐套的数据全部引入?解决办法:将正在目前使用的帐套输出后,替换后缀名为.lst的文件中记录的所有原帐套号为新帐套号,帐套的路径也要修改。也可以用sql提供的强制恢复进行处理。
科目设置中日记账对方科目按照账号设置时只能选择银行账号么,现金账号不能选择 科目设置中日记账对方科目按照账号设置时只能选择银行账号么,现金账号不能选择[]
补丁解决了不能设置现金帐号的问题,请备份账套到社区~产品更新下载补丁执行。@服务社区刘小艳:已经更新了最新补丁,但是到账套里还是不能设置@服务社区刘小艳:@科航019:红色账套点击升级。
科目设置了项目核算,多栏账里面是否就不能再去设置查询了?如果有这样的需求,应该去查哪张表? 科目设置了项目核算,多栏账里面是否就不能再去设置查询了?如果有这样的需求,应该去查哪张表?[]
多栏账只适合有下级会计科目的情况进行查询,设置了项目辅助核算,可以查询科目项目余额表或者明细账项目辅助账里,有项目多栏式明细账,但是,也只是限制于有下级会计科目的带项目辅助核算的情况下进行查询
| Copyright &
www.kuaiji66.com &All Rights Reserved 精彩会计生活 &北京天龙瑞德&版权所有 & 北京海淀上地十街辉煌国际大厦3-609&总机:010- & 售后:在C语言中模拟含有默认参数的函数
【好久没写了,来篇技术科普文】
写C++代码的时候总想当然以为C中也有含默认参数的函数这种玩意儿(值得注意的是而,Scala这种奇葩支持是不足为奇的),然后在编译下面这段代码之后颜面扫尽TwT
#include &default_args.h&
void printString(const char* msg,int size,int style){
printf(&%s %d %d\n&,msg,size,style);
int main(){
printString(&hello&);
printString(&hello&,12);
printString(&hello&,12,bold);
#include&stdio.h&
plain=0,italic=1,bold=2
void printString(const char* msg,int size=18,int style=italic);
nonoob@nonoobPC$
clang default_args.c -o default_args
In file included from default_args.c:1:
./default_args.h:12:42: error: C does not support default arguments
clang果然是人性化的编译器,还会告诉我们真实的原因;不像gcc只会报出一堆慕名奇妙的error信息,读者不妨自己尝试一下,这里就不吐槽了。至于如果我们的目的在于只要编译通过的话,那完全可以无节操地把这段代码当成C++代码,然后用clang++或g++来搞定这一切;最多只是会报出一个warning(而如果把default_args.c换成default_args.cpp的话连clang++都不报任何警告):
clang: warning: treating 'c' input as 'c++' when in C++ mode, this behavior is deprecated
传说中程序员只关心error而不管warning,那大可就此打住并到stackoverflow的上灌水一番。不过如果是那种闲着无聊且非常执着的话(或者是那种没法用C++而只能选择C的情况,抑或是那种考虑到在其他C的源文件中用到printString()函数的情况),那不妨往下看。一个很容易想到的解决方案自然是重载函数了(先不管效率)。在default_args.c删掉函数中的默认值并添加下面这段:
void printString(const char *msg,int size){
printString(msg,size,italic);
nonoob@nonoobPC$
clang override_args.c -o override_args
override_args.c:14:6: error: conflicting types for 'printString'
又一次颜面扫尽,C原来连重载函数都不支持&_&,弱爆了。没辙了吗?就不能猥琐地模拟一下然后让C语言程序员也享受一下默认参数的快感吗?macro!C程序员的必杀技,一个被C++程序员吐槽无数的招数:-(,但却是一个很优雅的解决方案^_^
#include&stdio.h&
plain=0,italic=1,bold=2
void printString(const char* message, int size, int style) {
printf(&%s %d %d\n&,message,size,style);
#define PRINT_STRING_1_ARGS(message)
printString(message, 18, italic)
#define PRINT_STRING_2_ARGS(message, size)
printString(message, size, italic)
#define PRINT_STRING_3_ARGS(message, size, style) printString(message, size, style)
#define GET_4TH_ARG(arg1, arg2, arg3, arg4, ...) arg4
#define PRINT_STRING_MACRO_CHOOSER(...) \
GET_4TH_ARG(__VA_ARGS__, PRINT_STRING_3_ARGS, \
PRINT_STRING_2_ARGS, PRINT_STRING_1_ARGS, )
#define PRINT_STRING(...) PRINT_STRING_MACRO_CHOOSER(__VA_ARGS__)(__VA_ARGS__)
int main(int argc, char * const argv[]) {
PRINT_STRING(&Hello, World!&);
PRINT_STRING(&Hello, World!&, 12);
PRINT_STRING(&Hello, World!&, 12, bold);
看到这么一坨代码,估计没几个人喜欢&&宏这种对把源代码看成白盒的程序员实在不友好的东西,然而却让所有的C程序员大受其益。不妨看一下NULL的定义:
#define NULL ((void *)0)
闲话不扯了,看看前段代码是怎么回事;毕竟子曾曰过:举一隅不以三隅反,则不复也。
macro本身也不是什么见不得人的东西,说到底就是方便程序员偷懒的,在实现的最终目的上和函数没有本质区别。这里需要注意的是__VA_ARGS__这个东东。其洋名叫Variadic Macros,就是可变参数宏,在这里是配合&...&一起用的。可变参函数想必C程序员都不陌生,就是没吃过猪肉也见过猪跑是吧,比如printf;。我们在这里需要知道的是宏定义(define)处的&...&是可以和宏使用(use)处的多个参数一起匹配的。下面以PRINT_STRING(&Hello, World!&, 18);为例说明是怎么展开的。
首先&Hello,World!&, 12匹配PRINT_STRING_MACRO_CHOOSER(...)中的&...&,于是被扩展成:
PRINT_STRING_MACRO_CHOOSER(&Hello, World!&, 12)(&Hello, World!&, 12);
而PRINT_STRING_MACRO_CHOOSER(&Hello, World!&,12)又被扩展成
GET_4TH_ARG(&Hello, World!&, 12, PRINT_STRING_3_ARGS, PRINT_STRING_2_ARGS, PRINT_STRING_1_ARGS, )
所以整条语句被扩展成了
GET_4TH_ARG(&Hello, World!&, 12, PRINT_STRING_3_ARGS, PRINT_STRING_2_ARGS, PRINT_STRING_1_ARGS, )(&Hello, World!&, 12);
接下来看到的是匹配#define GET_4TH_ARG(arg1,arg2,arg3,arg4, ...)arg4的情况,&Hello,World!&匹配args1,12匹配arg2,PRINT_STRING_3_ARGS匹配arg3,PRINT_STRING_2_ARGS匹配arg4,而其余, PRINT_STRING_1_ARGS, 的部分匹配了&...&,所以经过这一番扩展变成了
PRINT_STRING_2_ARGS(&Hello, World!&, 12);
printString(&Hello, World!&, 12,1);
这样一番折腾终于见到庐山真面目了。当然我们可以用gnu cpp查看一下预处理的结果是不是这样的(一般来讲C和C++用preprocessor是一样的)。
int main(int argc, char * const argv[]) {
printString(&Hello, World!&, 18, italic);
printString(&Hello, World!&, 12, italic);
printString(&Hello, World!&, 12, bold);
这也解释了为什么说用macro的解决方案是优雅的。不妨再看看生成的llvm的ir形式:
nonoob@nonoobPC$
clang macro.c -S -o - -emit-llvm
; ModuleID = 'macro.c'
target datalayout = &e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32-S128&
target triple = &i386-pc-linux-gnu&
@.str = private unnamed_addr constant [10 x i8] c&%s %d %d\0A\00&, align 1
@.str1 = private unnamed_addr constant [14 x i8] c&Hello, World!\00&, align 1
define void @printString(i8* %message, i32 %size, i32 %style) nounwind {
%1 = alloca i8*, align 4
%2 = alloca i32, align 4
%3 = alloca i32, align 4
store i8* %message, i8** %1, align 4
store i32 %size, i32* %2, align 4
store i32 %style, i32* %3, align 4
%4 = load i8** %1, align 4
%5 = load i32* %2, align 4
%6 = load i32* %3, align 4
%7 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str, i32 0, i32 0), i8* %4, i32 %5, i32 %6)
declare i32 @printf(i8*, ...)
define i32 @main(i32 %argc, i8** %argv) nounwind {
%1 = alloca i32, align 4
%2 = alloca i32, align 4
%3 = alloca i8**, align 4
store i32 0, i32* %1
store i32 %argc, i32* %2, align 4
store i8** %argv, i8*** %3, align 4
call void @printString(i8* getelementptr inbounds ([14 x i8]* @.str1, i32 0, i32 0), i32 18, i32 1)
call void @printString(i8* getelementptr inbounds ([14 x i8]* @.str1, i32 0, i32 0), i32 12, i32 1)
call void @printString(i8* getelementptr inbounds ([14 x i8]* @.str1, i32 0, i32 0), i32 12, i32 2)
很清爽的代码,令人心旷神怡吧。
废了这么大的力气才做了这么点事,还不如不用&默认参数&呢是吧?但是当把这个写成库的时候,或者以后要经常使用的话这就方便多了,且不容易出错!
为了无聊起见,再看看default_org.h+default_org.c用clang++/g++编译得到的llvm的ir:
nonoob@nonoobPC$
clang++ default_args.c -S -o - -emit-llvm
clang: warning: treating 'c' input as 'c++' when in C++ mode, this behavior is deprecated
; ModuleID = 'default_args.c'
target datalayout = &e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32-S128&
target triple = &i386-pc-linux-gnu&
@.str = private unnamed_addr constant [10 x i8] c&%s %d %d\0A\00&, align 1
@.str1 = private unnamed_addr constant [6 x i8] c&hello\00&, align 1
define void @_Z11printStringPKcii(i8* %msg, i32 %size, i32 %style) {
%1 = alloca i8*, align 4
%2 = alloca i32, align 4
%3 = alloca i32, align 4
store i8* %msg, i8** %1, align 4
store i32 %size, i32* %2, align 4
store i32 %style, i32* %3, align 4
%4 = load i8** %1, align 4
%5 = load i32* %2, align 4
%6 = load i32* %3, align 4
%7 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str, i32 0, i32 0), i8* %4, i32 %5, i32 %6)
declare i32 @printf(i8*, ...)
define i32 @main() {
%1 = alloca i32, align 4
store i32 0, i32* %1
call void @_Z11printStringPKcii(i8* getelementptr inbounds ([6 x i8]* @.str1, i32 0, i32 0), i32 18, i32 1)
call void @_Z11printStringPKcii(i8* getelementptr inbounds ([6 x i8]* @.str1, i32 0, i32 0), i32 12, i32 1)
call void @_Z11printStringPKcii(i8* getelementptr inbounds ([6 x i8]* @.str1, i32 0, i32 0), i32 12, i32 2)
%2 = load i32* %1
ret i32 %2
从这里的IR中我们至少可以得到两点信息:
C++编译得到的函数名和C编译得到的不一样(事实上是很不一样,可以参见),使用c++filt之后我们可以看到C++中的printString的签名实际上是void @printString(char const*, int, int)(i8* %msg, i32 %size, i32 %style)而不再是void @printString(i8* %message, i32 %size, i32 %style)。同时这也解释了为何在C中不会有函数的(静态)重载(没有OO自然动态重载更无从说起)&&假设C有函数重载的话,会生成三个同名的函数,而C中调用函数时仅仅根据符号表中的函数名,这样就会造成混乱。【TODO:动态重载实现机理】
编译得到的代码中是看不到任何默认构造函数的信息的(同样连enum的信息也没有了),3条call指令中我们得到的只不过是对应下面源代码的指令(也没有生成三个签名不同但名字相同的函数printString())。
printString(&hello&,18,1);
printString(&hello&,12,1);
printString(&hello&,12,2);
到此为止,正文结束。下面贴捣鼓的一段含宏的代码~~
#include&stdio.h&
#include&stdarg.h&
#define LOGSTRING(fm,...) printf(fm,__VA_ARGS__)
#define MY_DEBUG(format,...) fprintf(stderr,NEWLINE(format),##__VA_ARGS__);
#define NEWLINE(str) str &\n&
#define GCC_DBG(format,args...) fprintf(stderr,format,##args)
#define DEBUG(args) (printf(&DEBUG: &), printf args)
#define STRING(str) #str
#define NULL 3
int main(int argc,char**argv){
LOGSTRING(&Hello %s %s\n&,&Hong&&xu&,&Chen&);
MY_DEBUG(&my debug&)
GCC_DBG(&gcc dbg\n&);
int n = 0;
if (n != NULL) DEBUG((&n is %d\n&, n));
puts(STRING(It really Compiles!));
参考资料:
http://stackoverflow.com/questions/3046889/optional-parameters-with-c-macros
http://www.cnblogs.com/alexshi/archive//2388453.html
Notify follow-up comments via e-mail
(type the code from the image)
or Ctrl+Enter}

我要回帖

更多关于 内联函数的好处与不足 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信