小编Bra*_*sen的帖子

普通C中的类型安全通用数据结构?

我做了比"普通的旧C"编程更多的C++编程.在普通C编程时,我非常想念的一件事是类型安全的通用数据结构,它是通过模板在C++中提供的.

为了具体起见,请考虑一般的单链表.在C++中,定义自己的模板类,然后根据需要对其进行实例化是一件简单的事情.

在C中,我可以想到一些实现通用单链表的方法:

  1. 编写链接列表类型和支持过程一次,使用void指针绕过类型系统.
  2. 编写预处理器宏,获取必要的类型名称等,以生成特定于类型的数据结构版本和支持过程.
  3. 使用更复杂的独立工具为您需要的类型生成代码.

我不喜欢选项1,因为它颠覆了类型系统,并且可能比特定类型的特定实现具有更差的性能.对于所有类型使用数据结构的统一表示,并向/从void指针进行转换,据我所知,需要一个间接性,这可以通过专用于元素类型的实现来避免.

选项2不需要任何额外的工具,但感觉有些笨拙,并且在使用不当时可能会导致错误的编译器错误.

选项3可以提供比选项2更好的编译器错误消息,因为专用数据结构代码将以扩展形式存在,可以在编辑器中打开并由程序员检查(而不是由预处理器宏生成的代码).但是,这个选项是最重量级的,一种"穷人的模板".之前我使用过这种方法,使用一个简单的sed脚本来专门化一些C代码的"模板化"版本.

我想用C而不是C++来编写我未来的"低级"项目,但是为每种特定类型重写通用数据结构的想法让我感到害怕.

人们对这个问题有什么经验?C中是否存在通用数据结构和算法的良好库,这些库不与选项1一起使用(即与void指针进行转换,这会牺牲类型安全性并增加间接级别)?

c generics code-generation data-structures

52
推荐指数
2
解决办法
2万
查看次数

在积极内联的情况下分析C++?

我试图找出我的C++程序花费时间的地方,使用gprof.这是我的困境:如果我使用我用于发布版本的相同优化设置进行编译,几乎所有内容都被内联,并且gprof告诉我,无益的是,我90%的时间花在核心例程中,其中所有内容都是内联的.另一方面,如果我使用内联禁用编译,程序运行速度会慢一个数量级.

我想知道当我的程序编译时启用内联时,从我的核心例程调用的程序花了多少时间.

我在四核Intel机器上运行64位Ubuntu 9.04.我查看了google-perftools,但这似乎不适用于x86_64.在32位计算机上运行不是一种选择.

当启用内联时,是否有人建议如何更有效地配置我的应用程序?

编辑:这是我的问题的一些澄清.如果最初不清楚,我道歉.

我想找到在我的应用程序中花费的时间.分析我的优化构建导致gprof告诉我,大约90%的时间花在main上,其中所有内容都是内联的.在剖析之前我已经知道了!

我想知道的是内联函数花了多少时间,最好不要在我的构建选项中禁用优化或内联.在使用内联禁用进行性能分析时,应用程序的速度会慢一个数量级.这种执行时间的差异是一个方便的问题,但是,我不确定使用内联禁用构建的程序的性能配置文件是否与使用内联启用的程序的性能配置文件强烈对应.

简而言之:有没有办法在不禁用优化或内联的情况下获得有关C++程序的有用的性能分析信息?

c++ profiling

18
推荐指数
2
解决办法
1463
查看次数

SQLite3的动态类型

与其他SQL版本相比,SQLite3使用动态类型而不是静态类型.在SQLite的网站上写着:

大多数SQL数据库引擎(除了SQLite之外的每个SQL数据库引擎,据我们所知)都使用静态,严格的类型.使用静态类型时,值的数据类型由其容器(存储值的特定列)确定.

SQLite使用更通用的动态类型系统.在SQLite中,值的数据类型与值本身相关联,而不是与其容器相关联.

在我看来,这正是你想要的,因为它允许你存储整数列中的字符串.

页面继续:

... SQLite中的动态类型允许它执行传统的刚性类型数据库中无法实现的操作.

我有两个问题:

  1. 用例问题:SQLite3的动态类型有哪些例子?
  2. 历史/设计问题:使用动态类型实现SQLite的动机是什么?

database sqlite dynamic-typing

18
推荐指数
2
解决办法
2271
查看次数

为什么我的程序在内存不足时会偶尔发生段错误而不是抛出std :: bad_alloc?

我有一个程序实现了几个启发式搜索算法和几个域,旨在通过实验评估各种算法.该程序是用C++编写的,使用GNU工具链构建,并在64位Ubuntu系统上运行.当我运行我的实验时,我使用bash的ulimit命令来限制进程可以使用的虚拟内存量,以便我的测试系统不会开始交换.

某些算法/测试实例组合达到了我定义的内存限制.大多数情况下,程序抛出一个std :: bad_alloc异常,由异常处理程序打印,此时程序终止.偶尔,程序只是段错误而不是这种情况发生.

为什么我的程序在内存不足时偶尔会出现段错误,而不是报告未处理的std :: bad_alloc并终止?

c++ segmentation-fault bad-alloc

11
推荐指数
1
解决办法
3735
查看次数

符合ANSI C的实现是否可以在其标准库中包含其他功能?

是否符合ANSI C标准的实现允许在其标准库中包含其他类型和函数,超出标准列举的那些类型和函数?(理想的答案将参考ANSI标准的相关部分.)

我特别要求,因为Mac OS 10.7 getline在stdio.h中声明了该函数,即使使用该-ansi标志使用gcc或clang进行编译也是如此.这打破了几个定义自己getline功能的旧程序.这是Mac OS 10.7的错吗?(getlineMac OS 10.7上的手册页说明getline符合2008年发布的POSIX.1标准.)

编辑:为了澄清,我发现奇怪的是,在Mac OS 10.7上的ANSI C89程序中包含stdio.h也会引入该getline函数的声明,因为getline它不是K&R(可能是ANSI)中所列举的函数之一. stdio.h中.特别是,尝试编译noweb:

gcc -ansi -pedantic    -c -o notangle.o notangle.c
In file included from notangle.nw:28:
getline.h:4: error: conflicting types for ‘getline’
/usr/include/stdio.h:449: error: previous declaration of ‘getline’ was here
Run Code Online (Sandbox Code Playgroud)

它是否是Mac OS 10.7中的一个错误,getline即使在编译ANSI C89标准时也包括stdio.h中的声明?

c standards ansi getline osx-lion

9
推荐指数
1
解决办法
1516
查看次数

如何防止QuickCheck捕获所有异常?

QuickCheck库似乎捕获了测试属性时抛出的所有异常.特别是,这种行为使我无法对整个QuickCheck计算设置时间限制.例如:

module QuickCheckTimeout where

import System.Timeout (timeout)
import Control.Concurrent (threadDelay)
import Test.QuickCheck (quickCheck, within, Property)
import Test.QuickCheck.Monadic (monadicIO, run, assert)

-- use threadDelay to simulate a slow computation
prop_slow_plus_zero_right_identity :: Int -> Property
prop_slow_plus_zero_right_identity i = monadicIO $ do
  run (threadDelay (100000 * i))
  assert (i + 0 == i)

runTests :: IO ()
runTests = do
  result <- timeout 3000000 (quickCheck prop_slow_plus_zero_right_identity)
  case result of
    Nothing -> putStrLn "timed out!"
    Just _  -> putStrLn "completed!"
Run Code Online (Sandbox Code Playgroud)

因为QuickCheck捕获了所有异常,所以timeout中断:它实际上并没有中止计算!相反,QuickCheck将属性视为失败,并尝试缩小导致失败的输入.然后,该缩小过程不会以时间限制运行,导致计算使用的总时间超过规定的时间限制.

有人可能会认为我可以使用QuickCheck的 …

testing haskell quickcheck

7
推荐指数
1
解决办法
364
查看次数