我刚刚阅读了GCC中的Statement Expressions Extension,我在使用它时发现了一些意想不到的行为。 请注意这个例子: #include int main(void) { char* res1 = ({ char arr[] ={‘h’, ‘e’, ‘\0’}; // was char *arr[] arr[0] = ‘x’; char* ptr = arr; ptr; }); char* res2 = ({ char arr[] ={‘h’, ‘e’, ‘\0’}; // was char *arr[] arr[0] = ‘X’; char* ptr = arr; ptr; }); printf (“%s %p\n”, […]
我是GCC的C矢量扩展的新手。 我正在考虑在我的项目中使用它们,但它们的实用性(在某种程度上)取决于能够有效地将向量中的所有元素向左移动一个位置并将结果存储在新向量中。 如何有效地完成这项工作(例如以SIMD加速方式)? 所以,基本上: OriginalVector = {1,2,3,4,5,6,7,8} ShiftedVector = {2,3,4,5,6,7,8,X}(其中X可以是任何东西。) 背景信息(你可以跳过这个):这种转换的目的是处理矩阵,其中每一行用向量表示。 具体来说,它可以使ShiftedVector视为下方行的左上对角线,并比较一个SIMD操作中的所有值。 如果有另一种方法将矢量与另一个矢量偏移一个元素进行比较,那么这也可以解决问题。 但我假设没有,并且执行此比较的最有效方法是向左移动所有元素并以1:1进行比较。 一般规定: 在此过程中不得损害原始载体 如果我必须使用某种类型的x86内部函数 ,这很好,但我不知道是哪种或如何 如果我丢失了向量中最左边的元素并且在最右边引入了乱码,这很好 如果最有效的方法是从第二个位置到结束+ 1的原始矢量的未对齐加载,那很好,但我仍然想知道如何最好地编码这个 这里的瓶颈似乎是缺乏关于使用内在函数的过程的一般信息。 似乎人们使用汇编(我不是专家)或自动矢量化( 这里不能很好地工作 ),因此矢量类型是最合乎逻辑的选择。 谢谢!
我正在用C写一个列表。以下是来源: #include #include struct list { int value; struct list *next; }; typedef struct list ls; void add (ls **head, ls **tail, int val) { ls *new, *tmp1, *tmp2; if (NULL == *head) { new = (ls*)malloc(sizeof(ls)); *head = new; *tail = new; new->value = val; new->next = NULL; return; } else { tmp1 = […]
我想从汇编中调用至少1个C函数。 这是因为我从头开始做我自己的小操作系统(无中生有)。 我想从我的启动加载程序调用c函数的原因。 我可以理解集会,但写自己的程序很差。 因此,如果我可以将控制从assembly程序转移到c程序,我的工作就变得更容易了。 那么如何将程序集pgm和C程序文件链接成一个。 即使文件大小超过512字节,也可以。 我在mingw的帮助下在Windows 7上这样做。 我的c编译器是gcc ,汇编器是nasm 。
当我在函数的参数中传递矩阵时,使用括号,我也需要传递列数。 为什么? #include //int function(int matrix[][5]){ //Will work int function(int matrix[][]){ //Won’t work return matrix[0][0]; } int main(){ int matrix[5][5]; matrix[0][0] = 42; printf(“%d”, function(matrix)); } gcc错误: prog.c:3:18: error: array type has incomplete element type int function(int matrix[][]){ ^ prog.c: In function ‘main’: prog.c:10:5: error: type of formal parameter 1 is incomplete printf(“%d”, function(matrix)); ^ […]
为什么GCC给我这个错误? 我在这做错了什么? temp.c: In function main: temp.c:6: error: invalid operands to binary + 码: main() { char *Address1,*Address2,*NewAddress; Address1= (char*)0x12; Address2= (char*)0x34; NewAddress = Address1+Address2; }
在Ubunutu 12.04或Springdale 6.4上,使用gcc和g ++, C_INCLUDE_PATH (或CPLUS_INCLUDE_PATH )和LD_LIBRARY_PATH之间的区别是什么? LD只在运行时使用,而其他两个只在编译时使用吗? 由于这些操作系统上的GCC似乎忽略了INCLUDE和LIBRARY_PATH环境变量,我应该在构建我的〜/ .bashrc文件时将其设置为使其在现代Linux操作系统中尽可能可移植(实际路径中的模数更改)?
C99和C11中的有效类型规则规定,可以使用任何类型写入没有声明类型的存储,并且存储非字符类型的值将相应地设置存储的有效类型。 撇开INT_MAX可能小于123456789的事实,以下代码对有效类型规则的使用是否严格符合? #include #include /* Performs some calculations using using int, then float, then int. If both results are desired, do_test(intbuff, floatbuff, 1); For int only, do_test(intbuff, intbuff, 1); For float only, do_test(floatbuff, float_buff, 0); The latter two usages require storage with no declared type. */ void do_test(void *p1, void *p2, int leave_as_int) { *(int*)p1 […]
我正在查看Atmel网站上的文档,我遇到了这个例子 ,他们解释了重新排序的一些问题。 这是示例代码: #define cli() __asm volatile( “cli” ::: “memory” ) #define sei() __asm volatile( “sei” ::: “memory” ) unsigned int ivar; void test2( unsigned int val ) { val = 65535U / val; cli(); ivar = val; sei(); } 在这个例子中,他们正在实现一个类似于关键区域的机制。 cli指令禁用中断,sei指令启用它们。 通常,我会保存中断状态并恢复到该状态,但我离题了…… 他们注意到的问题是,在启用优化的情况下,第一行上的除法实际上会在cli指令之后移动到。 当您尝试尽可能在最短的时间内进入关键区域时,这可能会导致一些问题。 为什么如果cli()MACRO扩展为内联asm明显破坏内存,这怎么可能呢? 编译器如何在此语句之前或之后自由移动? 另外,我修改了代码以在__asm volatile(“” ::: “memory”);forms的每个语句之前包含内存屏障__asm volatile(“” ::: “memory”); 它似乎没有改变任何东西。 […]
我写了一个像这样的矢量结构: struct vector { float x1, x2, x3, x4; }; 然后我创建了一个函数,它使用向量使用内联汇编执行一些操作: struct vector *adding(const struct vector v1[], const struct vector v2[], int size) { struct vector vec[size]; int i; for(i = 0; i < size; i++) { asm( "FLDL %4 \n" //v1.x1 "FADDL %8 \n" //v2.x1 "FSTL %0 \n" "FLDL %5 \n" //v1.x2 "FADDL %9 […]