Questions tagged «c»

C是用于操作系统,游戏和其他高性能工作的通用计算机编程语言。

4
每个C程序员必须注意哪些安全风险/漏洞?[关闭]
已关闭。这个问题需要更加集中。它当前不接受答案。 想改善这个问题吗?更新问题,使其仅通过编辑此帖子来关注一个问题。 4年前关闭。 与硬件的密切联系存在许多安全风险,这与使用高级编程语言经过测试和验证的API形成对比。与诸如Java之类的语言相比,用C引起缓冲区溢出要容易得多。 每个C程序员都应该意识到哪些风险或漏洞(例如缓冲区溢出)(与C程序员相关的IE漏洞)?这些可能导致什么问题?如何避免它们,以及导致这些错误在程序中发生的常见错误是什么?

3
新的C项目何时应针对非常老的C标准(> 20年,即C89)?
偶尔我会看到针对较旧的C标准(通常是C89)的大型,相对较新的开源C项目。有一个例子。这些项目由聪明的人掌舵,因此他们可能对这个我不知道的决定有很好的理由。除了疑问的好处之外,似乎基本原理是“较老和标准化总是更具可移植性和更好性”,这是荒谬的,因为逻辑结论是FORTRAN优于C,COBOL甚至比FORTRAN更好。 什么时候以及为什么有理由要求新的C项目针对非常老的C标准? 我无法想象用户系统绝对不能更新其C编译器而可以自由安装新软件的情况。例如,Debian的LTS版本具有gcc 4.6软件包,该软件包支持C99和某些C11。我猜想肯定会存在奇怪的情况,而像systemd这样的程序正是针对这些用户的。 我能想到的最合理的用例是,预期用户将具有异国情调的体系结构,在该体系结构上只有 C89编译器可用,但他们完全愿意安装新软件。鉴于指令集体系结构多样性的下降,这似乎是一个过度假设的场景,但我不确定。
12 c  standards 

5
在嵌入式系统中为单个阵列分配大量堆栈有缺点吗?
我通常可以毫无疑问地确定某些数据是全局的,静态的还是在堆栈上(这里没有动态分配,因此不使用堆)。我也看过几个Q / A如这一个,但我的问题是更具体的,因为它涉及到比较系统内存中的数据,庞大的数额巨大。 我正在尝试改进的现有代码(设计,可能出现的问题,性能等)。该代码在只有4KB RAM的旧8位MCU上运行。在这段代码中,我将使用几乎1KB的数组(是的,在4KB RAM系统上为1KB)。使用此数组的每个字节,这不是问题。问题在于此数组是文件在其中声明的静态数组,因此其生命周期与程序之一相同(即可以视为无限)。 但是,在阅读了代码之后,我才发现该数组不需要无限的生命周期,它是以完全过程性的方式构建和处理的,因此我们应该只能在使用它的函数中声明它,这样,它将在堆栈上,因此我们将节省此1KB RAM。 现在的问题是:这是个好主意吗?从设计的角度来看,如果不需要无限/全局生命周期,则它属于堆栈。但是,嘿,这是4KB中的1KB,这样分配25%的RAM是否没有任何缺点?(可能是堆栈的50%或更多) 有人可以在这种情况下分享经验吗,还是有人在考虑是否有任何合理的理由不将此数组放在堆栈中?我正在寻找技术缺陷以及对设计的评论。 我唯一意识到的是,进入此功能时,我必须确保实际上有1KB的可用堆栈。也许这就是我必须采取的所有措施,也许不是。

2
为什么在C 2011中将可变长度数组设为可选?
在C 1999中引入VLA时,我认为这是对该语言的一项伟大创新。但是,在了解到它在C 2011中成为可选功能后,我想知道是什么导致了它的状态更改,以及这是否意味着该功能实际上即将过时。如果是这样,是否有等效的自动大小动态数据管理概念被认为可以替代它? 我试图找到C 2011基本原理文档,但该文档似乎尚未发布。

3
通过指针算术而不是[]运算符引用访问数组元素是否不好?
我刚刚开始学习用C编程,并且为了提高对指针和数组的理解,我尝试引用数组的元素而根本不创建任何指针: for(k1 = 0; k1 < ROW; k1++){ for(k2 = 0; k2 < COLUMN; k2++){ array[k1][k2] = k1*COLUMN + k2 + 1; printf("[%d][%d] = %d\n", k1, k2, *(array[k1] + k2)); } } 整个代码可以编译并完美运行。 我想必须在大型源代码中为每个数组创建一个指针似乎效率很低。 因此,与其使用指针存储和检索数组的地址,不如上面所示,直接使用数组的地址是一种不好的编程习惯吗?

2
为什么C仍属于高级语言类别?[关闭]
已关闭。这个问题是基于观点的。它当前不接受答案。 想改善这个问题吗?更新问题,以便通过编辑此帖子以事实和引用的形式回答。 5年前关闭。 许多有关C编程语言的教科书都说C是一种高级编程语言,但是许多在线辅导老师都说C也是一种中级编程语言。为什么会这样呢?

1
是否有任何值得注意的C扩展名包括其行为与机器字长无关的整数类型
与其他一些语言相比,C的一个有趣特征是它的许多数据类型基于目标体系结构的字长,而不是用绝对术语指定。虽然这允许该语言用于在某些类型可能有困难的机器上编写代码,但是这使得设计将在不同体系结构上一致运行的代码变得非常困难。考虑以下代码: uint16_t ffff16 = 0xFFFF; int64_t who_knows = ffff16 * ffff16; 在int16位(许多小型微控制器仍然适用)的体系结构上,此代码将使用定义良好的行为将值分配为1。在int64位机器上,它将再次使用定义良好的行为分配值4294836225。在int32位机器上,它可能会分配-131071的值(我不知道这是实现定义的还是未定义的行为)。即使代码只使用名义上称为“固定大小”类型的内容,该标准也要求当今使用的两种不同类型的编译器将产生两种不同的结果,而当今许多流行的编译器将产生三分之一。 这个特定的示例有些人为的,因为我不希望在现实世界的代码中将两个16位值的乘积直接分配给一个64位值,但是它被选择作为一个简短的示例来展示整数的三种方式促销可能与固定大小的无符号类型进行交互。在现实世界中,有必要根据数学整数算术规则对无符号类型的数学进行运算;在其他情况下,有必要根据模数运算的规则进行无符号类型运算;而在某些实际情况下,实际情况并非如此。没关系。诸如校验和之类的许多现实世界代码都依赖于uint32_t算术包装mod2³²,并且能够执行任意uint16_t 算术和获得的结果至少被定义为准确的mod 65536(与触发未定义行为相反)。 尽管这种情况显然似乎是不希望的(并且随着64位处理成为许多用途的规范,这种情况将变得越来越多),但据我所观察到的C标准委员会更喜欢引入已在某些著名产品中使用的语言功能。环境,而不是“从头开始”发明它们。C语言是否有任何显着扩展,这些扩展允许代码不仅指定如何存储类型,而且还指定在涉及可能晋升的场景中其应如何表现?我至少可以看到编译器扩展解决此类问题的三种方式: 通过添加一条指令,该指令将指示编译器将某些“基本”整数类型强制为一定大小。 通过添加一条指令,该指令将指示编译器评估各种升级方案,就像计算机的类型具有特定的大小一样,而与目标体系结构上类型的实际大小无关。 通过允许声明具有特定特征的类型(例如,声明一个类型应表现为mod-65536环绕的代数环,而不管其底层字长如何,并且不应隐式转换为其他类型;将a加到a wrap32上int应产生a类型的结果(wrap32无论是否int大于16位),而将a wrap32直接添加到a wrap16应该是非法的(因为两个都不能转换为另一个)。 我自己的选择是第三个选择,因为它甚至可以使具有异常字长的机器也可以使用很多代码,这些代码希望变量像“二次幂”一样“自动换行”。编译器可能必须添加位屏蔽指令以使该类型具有适当的性能,但是如果代码需要包装mod 65536的类型,则最好让编译器在需要它的机器上生成此类屏蔽,而不是使源代码杂乱无章。或者在需要掩蔽的机器上根本无法使用此类代码。我很好奇,但是,是否有任何通用扩展可以通过上述任何一种方式,或者通过我没有想到的某种方式来实现可移植的行为。 为了澄清我在找什么,有几件事;最为显着地: 尽管可以通过多种方式来编写代码,以确保所需的语义(例如,定义宏以对特定大小的无符号操作数执行数学运算,以产生明确包装或不包装的结果),或至少防止不希望的情况语义(例如,有条件地定义一个类型wrap32_t是uint32_t在编译器,其中一个uint32_t也不会得到提升,而这一数字是更好地为需要的代码wrap32_t到一些机器上该类型将得到提升,而不是有它运行并产生虚假行为失败编译)如果有任何一种编写代码的方式对将来的语言扩展最有利,那么使用该方式将比设计自己的方法更好。 对于如何扩展语言以解决许多整数大小的问题,我有一些很扎实的想法,允许代码在具有不同字长的机器上产生相同的语义,但是在我花大量时间编写它们之前,我想知道已经朝这个方向做了什么努力。 绝不希望我鄙视C标准委员会或他们所做的工作;但是,我希望在几年后,有必要使代码在“自然”升级类型为32位以及64位的计算机上正确工作。我认为,对语言进行一些适度的扩展(比C99 nnd C14之间的许多其他更改更适度),不仅可以提供一种有效使用64位体系结构的简洁方法,而且在讨价还价中还可以促进与该标准历来向后弯腰以支持“不寻常字长”的机器(例如,使具有12位的机器char可以运行期望uint32_t包装mod2³²]。根据未来扩展的方向,我还希望可以定义宏,这些宏将使今天编写的代码可在默认整数类型表现为“预期”的当今编译器上使用,也可在未来整数使用的编译器上使用类型将默认具有不同的行为,但是在哪里可以提供所需的行为。

2
为什么不能在C中将数组作为函数参数传递?
继此评论,我试图谷歌为什么,但我的谷歌福失败。 来自链接的评论: [...]但重要的是,数组和指针在C中是不同的东西。 假设您没有使用任何编译器扩展,通常就不能将数组本身传递给函数,但是可以传递指针,并像建立数组一样对指针进行索引。 您实际上在抱怨指针没有附加长度。您应该抱怨数组不能作为函数参数传递,或者数组隐式降级为指针。
12 c  history 

3
如何在C和C ++程序中标记类型?
在我的这个答案中,我_t在类型的末尾使用了它,但这种情况最多是有争议的。这是我在当前项目中使用的做法。 typedef struct { int x; int y; } point_t; 旨在与来自stddef.hlike size_t或C的C类型一致ptrdiff_t。但是,根据我的问题中的某些评论,_t后缀似乎是为POSIX保留的。我应该用什么代替_t?还是应该继续使用_t? 这个问题是针对C和C ++的。如果这些语言有不同的约定,请随时回答。
12 c++  c  naming 

3
是否可以将高级语言编译为可读的C ++?[关闭]
已关闭。这个问题是基于观点的。它当前不接受答案。 想改善这个问题吗?更新问题,以便通过编辑此帖子以事实和引用的形式回答。 6年前关闭。 C ++从许多方面来说都是一门伟大的语言,但是如果没有IDE编写某些东西特别麻烦。作为VIM用户,如果我可以使用更高级的语言,使我能够使用S-Expressions以及可能的类似Lisp的宏编写C ++,这将非常有趣,从而可以生成简洁的代码,同时避免重写相同的模式再三,一而再再而三。 我已经问过freenode并测试了一些想法,例如使用ECL和Bigloo等编译器编译Lisp-> C,但是没有一个生成特别干净的C代码。 在这个问题上有什么作品吗?

4
是否可以在Linux上使用Intel C / C ++编译器来创建要在Windows上链接的目标文件?
为什么? 取决于您的来源,英特尔编译器很可能或最肯定会为x86架构生成最快的可执行文件(将执行时间缩短5%至100%)。 英特尔根据非商业许可证免费提供其Linux编译器(我认为我在其页面上的某处免费阅读了该文件:英特尔-非商业软件开发)。还有一个针对学生的免费非商业许可证,但是尽管为所有三个主要操作系统都提供了工具(由于信誉限制而导致链接断开),但该许可证不适用。 目标 我(作为非学生)希望能够使用英特尔编译器来提高非商业许可下的执行速度,以编译可链接以创建Windows(可能是OS)的可执行文件和动态链接库的目标文件。 X) 更多细节: 从本文档中可以推断出,英特尔编译器会创建与平台的主流编译器兼容的目标文件。 子问题: Windows和Linux(当前版本)上的gcc,g ++,cl,mingw32,icc,icpc和icl的目标文件格式是什么? mingw32交叉编译器工具链的一部分可以用来实现目标吗? 我认为生成的目标文件中的元数据是主要问题吗? 广告2: mingw32-objcopy似乎能够将Linux(可能是ELF)上的Intel编译器输出转换为与Microsoft兼容的COFF(可重定位目标文件可能除外)。有人可以确认这确实有效吗(适用于非平凡的应用程序)?

5
要将git版本集成为内部版本号?
我和一个同事轮流讨论/讨论在构建时将从当前git存储库派生的版本集成到我们的代码中的问题/优点。 我们认为优点包括: 无需担心人为错误更新版本号 我们在设备中找到的内容与源于它的源代码之间的可追溯性 (对我们而言)出现的问题包括: IDE派生的构建系统(例如MPLABX)可能很难弄清楚将这些挂钩放置在何处(最终可能会很俗气) 实际将其集成到构建脚本/ makefile中的更多工作 耦合到特定的构建方法(例如,如果一个人使用XCode和另一个MPLABX进行构建怎么办)可能会给下游带来意外 因此,我们很好奇其他人在这场辩论中的地位。讨论变得容易流传开来。那里有很多人坚持端到端的自动化,把大量的前期工作挂在了一起,并耦合了它带来的影响。辩论的另一端还有很多其他人,他们所做的最简单的事情就是行之有效,并且承受风险。 对于哪一方最好着陆有合理的答案吗?
12 c  git  builds  build-system 

2
“可能”和“不太可能”宏的使用量太多了?
通常称为likely和的unlikely宏可帮助编译器了解if通常是要输入还是要跳过的。使用它可以带来一些(而不是很小的)性能改进。 我最近开始使用它们,我不确定应该多久使用一次此类提示。我目前将其与错误检查ifs 配合使用,通常将其标记为unlikely。例如: mem = malloc(size); if (unlikely(mem == NULL)) goto exit_no_mem; 看起来还可以,但是错误检查if经常发生,因此使用了所述宏。 我的问题是,是不是太有likely和unlikely宏的每个错误的检查if? 当我们在这里时,他们经常在其他什么地方使用? 在我当前的用法中,它位于从实时子系统进行抽象的库中,因此程序可以在RTAI,QNX和其他程序之间移植。也就是说,大多数功能都很小,可以直接调用一个或两个其他功能。许多甚至是static inline功能。 因此,首先,它不是我可以描述的应用程序。“识别瓶颈”是没有意义的,因为它是一个库,而不是一个独立的应用程序。 其次,有点像“我知道这不太可能,我不妨告诉编译器”。我没有积极尝试优化if。

9
Greenspun的第十条规则,每个大型项目都包括Lisp解释器吗?[关闭]
已关闭。这个问题是基于观点的。它当前不接受答案。 想改善这个问题吗?更新问题,以便通过编辑此帖子以事实和引用的形式回答。 6年前关闭。 Greenspun的第十条规则(实际上是唯一一条规则)指出: Any sufficiently complicated C or Fortran program contains an ad hoc, informally-specified, bug-ridden, slow implementation of half of Common Lisp. 我的记忆是,有一些关于该主题的论文,也许是针对Borland的Quattro(电子表格)项目的,可能还有其他论文。Google没有帮助,也许没有想到合适的搜索词。我正在寻找支持该主张的论文或文章。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.