小编Krz*_*icz的帖子

了解C11类型层次结构

我想完全理解C11语言的类型层次结构并以图形方式呈现它(树形图将是完美的).该标准没有提供任何关于这个问题的数字 - 有30个点描述了它们之间的各种类型和关系.我想画它.

我的尝试始于获得ISO/IEC 9899:201x委员会草案N1570并从文件第6.2.5节中提取所有必要的陈述.然后,我开始以树的形式重新安排知识.让我分两步介绍我的工作.

第1步:第1-15点

提取的知识(第6.2.5节+指定生产内的点):

  • 1 种类型 = 对象类型 + 函数类型 ;
  • 4个标准符号整型 = signed char,short int,int,long int,long long int;
  • 4个有符号整数类型 =标准有符号整数类型+ 扩展有符号整数类型 ;
  • 6个标准无符号整型 = _Bool,unsigned char,unsigned short int,unsigned int,unsigned long int,unsigned long long int;
  • 6个无符号整数类型 =标准无符号整数类型+ 扩展无符号整数类型 ;
  • 7种标准整数类型 =标准有符号整数类型+标准无符号整数类型;
  • 7个扩展整数类型 =扩展有符号整数类型+扩展无符号整数类型;
  • 10种实浮点类型 = float,double …

c standards types language-lawyer c11

34
推荐指数
1
解决办法
1293
查看次数

中缀vs前缀语法:名称查找差异

C++中的运算符通常被认为是函数/方法的替代语法,尤其是在重载的上下文中.如果是这样,下面的两个表达式应该是同义词:

std::cout << 42;
operator<<(std::cout, 42);
Run Code Online (Sandbox Code Playgroud)

实际上,第二个语句会导致以下错误:

call of overloaded ‘operator<<(std::ostream&, int)’ is ambiguous
Run Code Online (Sandbox Code Playgroud)

像往常一样,这样的错误信息附有可能的候选人名单,这些是:

operator<<(basic_ostream<_CharT, _Traits>& __out, char __c)
operator<<(basic_ostream<char, _Traits>& __out, char __c)
operator<<(basic_ostream<char, _Traits>& __out, signed char __c)
operator<<(basic_ostream<char, _Traits>& __out, unsigned char __c)
Run Code Online (Sandbox Code Playgroud)

这种错误至少引发了两个问题:

  1. 这两个语句以什么方式不同(在名称查找方面)?
  2. 为什么失踪?operator<<(basic_ostream<char, _Traits>& __out,int__c)

看起来,中缀和前缀符号不是完全可互换的 - 不同的语法需要不同的名称解析策略.有什么区别,它们来自哪里?

c++ syntax iostream operator-overloading

22
推荐指数
1
解决办法
640
查看次数

高效的4x4矩阵乘法(C vs汇编)

我正在寻找一种更快,更棘手的方法来将C中的两个4x4矩阵相乘.我目前的研究主要集中在具有SIMD扩展的x86-64汇编上.到目前为止,我已经创建了一个函数,比一个简单的C实现快6倍,这超出了我对性能改进的期望.不幸的是,只有在没有使用优化标志进行编译时(GCC 4.7),这种情况才会成立.随着-O2,C变得更快,我的努力变得毫无意义.

我知道现代编译器利用复杂的优化技术来实现几乎完美的代码,通常比巧妙的手工装配更快.但在少数性能关键的情况下,人类可能会尝试使用编译器争取时钟周期.特别是,当一些支持现代ISA的数学可以被探索时(就像我的情况一样).

我的函数如下(AT&T语法,GNU汇编程序):

    .text
    .globl matrixMultiplyASM
    .type matrixMultiplyASM, @function
matrixMultiplyASM:
    movaps   (%rdi), %xmm0    # fetch the first matrix (use four registers)
    movaps 16(%rdi), %xmm1
    movaps 32(%rdi), %xmm2
    movaps 48(%rdi), %xmm3
    xorq %rcx, %rcx           # reset (forward) loop iterator
.ROW:
    movss (%rsi), %xmm4       # Compute four values (one row) in parallel:
    shufps $0x0, %xmm4, %xmm4 # 4x 4FP mul's, 3x 4FP add's 6x mov's per row,
    mulps %xmm0, %xmm4        # expressed in four sequences of 5 instructions,
    movaps …
Run Code Online (Sandbox Code Playgroud)

c optimization assembly sse matrix-multiplication

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

C11表达式中的赋值运算符排序

介绍

C11标准(ISO/IEC 9899:2011)在表达式中引入了新的副作用测序定义(参见相关问题).该序列点概念已经补充了之前测序后序关系,这是现在所有定义的基础.

第6.5节"表达式",第2点说:

如果相对于对同一标量对象的不同副作用或使用相同标量对象的值进行值计算,对标量对象的副作用未被排序,则行为未定义.如果表达式的子表达式有多个允许的排序,则如果在任何排序中发生这种未测序的副作用,则行为是不确定的.

稍后,第6.5.16节"分配操作员",第3点指出:

在左右操作数的值计算之后,对更新左操作数的存储值的副作用进行排序.对操作数的评估是不确定的.

问题

第一个引用的段落(6.5/2)由两个例子支持(与C99标准相同):

第一个例子

a[i++] = i;  //! undefined
a[i] = i;    //  allowed
Run Code Online (Sandbox Code Playgroud)

这可以通过以下定义轻松解释:

  1. 如果相对于(...)使用相同标量对象的值进行值计算,标量对象的副作用未被排序,则行为未定义.(6.5/2),
  2. 对操作数的评估是不确定的.[在作业内](6.5.16/3).

因此,i++(LHS)的副作用与i(RHS)无关,这给出了不确定的行为.

第二个例子

i = ++i + 1; //! undefined
i = i + 1;   //  allowed
Run Code Online (Sandbox Code Playgroud)

但是,此代码似乎在两种情况下都会导致定义的行为:

  1. 在左右操作数的值计算之后,对更新左操作数的存储值的副作用进行排序.

因此,执行++i + 1 应该在更新的副作用之前i,这意味着相对于对同一标量对象的不同副作用或使用相同标量的值的值计算,对未标测的标量对象没有副作用宾语.

使用C99标准提出的术语和定义很容易解释这些例子(参见相关问题).但i = ++i + 1根据C11的术语,为什么不明确?

c expression undefined-behavior language-lawyer c11

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

单独编译相互依赖的C模块

假设我们有一组相互依赖的C模块,我们想创建一个GNU Makefile,用于为几个不同的构建(例如,单元测试,用户工具,多个版本)单独编译它们.

每个模块虽然对整个应用程序至关重要,但它们可以单独使用,也可以与其他模块以任何合理的组合方式使用 - 始终暴露最具特色的API,这些API是由为特定构建选择的其他模块提供的组件的可用性产生的.

为了一个最小和完整的例子,让我们假设我们的程序有三个模块(红色,绿色和蓝色),所有可能的条件功能都通过条件编译来切换.每个模块具有两个这样的条件块,每个条件块由两个可能的邻居之一的存在来启用.这为我们提供了三种可能的单一构建(红色,绿色,蓝色),三种双重构建(青色,洋红色,黄色)和一种三重构建(白色) - 每个构建都包含一个专用的主程序(Core),构建在一组构建的特征.

期望的情况

理想的情况

图1示出了三个模块(mod_red.c,mod_green.cmod_blue.c«RGB»); 在相邻模块实现三个跨模块功能区域(青色,品红色和黄色«CMY»); 和三个核心(白色,具有物理依赖性«RGB»在大的,锐化的顶部和逻辑依赖性«CMY»在小顶部).每个方向(六个中的一个)表示功能方面,因此CMY顶部指向主三角形表明协同作用可以提供额外的特征.

期望的Makefile应该为所有可能的构建提供配方,因此使用三个模块和七个不同核心中的每一个的四个版本.它应该足够聪明,以避免残酷的解决方案(gcc每个配方的完整命令块)并保持单独编译的优势.

没有单独的编译,问题很容易(至少对于单边依赖):主程序包括必要的源,并且依赖块由预处理器标志启用,例如由其他模块包括保护器设置的那些.但是,通过单独编译,编译器不知道包含特定构建的模块集.

手动方法

可以使用下面列出的shell命令手动实现所需的情况.

# Single objects:
gcc -c -o mod_green.o mod_green.c

# Double objects
gcc -c -include mod_blue.h -o mod_red+B.o mod_red.c
gcc -c -include mod_red.h -o mod_blue+R.o mod_blue.c

# Triple objects
gcc -c -include mod_green.h -include mod_blue.h -o mod_red+G+B.o mod_red.c
gcc -c -include mod_red.h -include mod_blue.h -o mod_green+R+B.o mod_green.c
gcc -c -include mod_red.h …
Run Code Online (Sandbox Code Playgroud)

c gcc makefile compilation

5
推荐指数
1
解决办法
952
查看次数

GTK +和OpenGL库如何在单个X服务器上协作?

图形用户界面隐藏着神秘的机制.它在单个屏幕上混合2D和3D上下文,并允许这两个不同的世界的无缝组合.但是它们以什么方式和在哪个级别实际交错?

实践表明,OpenGL上下文可以嵌入到2D小部件库中,因此可以使用OpenGL支持整个2D界面.一些应用程序可能会探索硬件加速,而其他应用程序则不会(在同一屏幕上渲染时).图形卡是否"知道"屏幕上的2D和3D区域,窗口管理器是否会产生一个有凝聚力的前端的错觉?...当例如滚动网页或在屏幕上移动视频播放器时,可以注意到加速窗口(3D,视频)"跳跃"以适应2D界面.

这个问题似乎微不足道,但我没有遇到任何能够给我一个全面答案的人.答案,这使我能够将OpenGL上下文嵌入到GTK +应用程序中,并了解其工作原理和方式.我已经尝试过GtkGlExt和GLUT,但我想深入理解这个主题,并将自己的解决方案作为学术项目的一部分.我想知道X,GLX,GTK,OpenGL和窗口管理器之间的关系是什么,以及如何探索这个库网络以有意识地编程它.

我不希望有人在这里写论文,但我会感谢任何有关该主题的文章的指示,建议或链接.

gtk opengl user-interface

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