Tag: 编译器构造

是否可以在Linux上没有链接libc的情况下将C转换为asm?

测试平台在Linux 32位上。 (但也欢迎Windows 32位上的某些解决方案) 这是交响代码段: int a = 0; printf(“%d\n”, a); 如果我使用gcc生成汇编代码 gcc -S test.c 然后我会得到: movl $0, 28(%esp) movl 28(%esp), %eax movl %eax, 4(%esp) movl $.LC0, (%esp) call printf leave ret 而这个汇编代码需要链接到libc才能工作(因为调用printf) 我的问题是: 是否可以将C转换为asm,只使用显式使用系统调用 ,而不使用libc? 像这样: pop ecx add ecx,host_msg-host_reloc mov eax,4 mov ebx,1 mov edx,host_msg_len int 80h mov eax,1 xor ebx,ebx int 80h […]

使用Unicode行分隔符编译UTF-8编码的源

使用最新版本的Microsoft Compiler(包含在Win7 SDK中),我试图编译一个使用UTF-8编码的源文件和unicode行分隔符。 不幸的是,即使我在文件的开头包含UTF-8签名,代码也不会编译。 例如,如果我尝试编译它: #include int main (void) { printf(“Hello!”); return 0; } 我会看到以下错误: 提示> cl test.c Microsoft(R)32位C / C ++优化编译器版本15.00.30729.01 for 80×86版权所有(C)Microsoft Corporation。 版权所有。 test.c test.c(1):警告C4067:预处理器指令后面的意外令牌 – 预期换行符Microsoft(R)Incremental Linker Version 9.00.30729.01版权所有(C)Microsoft Corporation。 版权所有。 /out:test.exe test.obj LINK:致命错误LNK1561:必须定义入口点 以前有人遇到过这个问题吗? 有解决方案? 谢谢! 安德鲁

在编译的哪个阶段保留标识符?

在这里工作只是一点点好奇心。 在处理危险的事情时,我开始考虑各种编译器及其相关标准库的实现。 这是我思想的进展: 某些类的标识符保留用于C ++和C中的实现。 编译器必须执行编译阶段(预处理,编译,链接),就好像它们是按顺序执行一样。 C预处理器不知道标识符的保留状态。 因此, 当且仅当以下情况时,程序可以使用保留标识符: 使用的保留标识符是所有预处理器符号。 预处理结果不包括保留标识符。 标识符与编译器预定义的符号不冲突( GNUC等人) 这有效吗? 我对第3点和第4.3点不确定。 此外,有没有办法测试它?

链接步骤找不到符号(XC8编译器)

我正在尝试使用XC8编译器编译和链接C程序。 我改变了C18编译器并对代码进行了一些小的兼容性更改。 使用C18,编译和链接的代码就好了。 使用XC8,编译很顺利,但链接步骤失败并出现此错误: Error [500] ; 0. undefined symbols: _putch(server.obj) _ENC_Init(server.obj) _ENC_WriteRegister(server.obj) _ENC_ReadRegister(server.obj) 由于编译成功,我猜有原型,ergo .h文件包含好。 我猜编译器找不到.c文件。 函数putch 不是在我自己的程序中调用的,但它在putchar调用,我使用该函数。 以ENC_开头的函数是我自己的函数。 我在XC8工具套件的“包含搜索路径”中添加了两条路径: C:\Program Files (x86)\Microchip\xc8\v1.12\sources ,编译器的.c文件所在的位置,我相信 C:\…\lib ,我自己的.c文件所在的位置。 但是,我仍然得到错误。 我该如何解决这个问题? 这是完整的日志: Advisory[1233] Employing 18F4620 errata work-arounds: Advisory[1234] * Corrupted fast interrupt shadow registers Advisory[1234] * Data in RAM location can be corrupted if async. reset occurs […]

C vs C ++中的typedef和struct命名空间

我试图在一些新的C ++中使用一些旧的C库。 该库的头文件使用D. Hanson的“C接口和实现”实现隐藏成语: #define T MyAST typedef struct T *T; 接近我可以说,这用C编译,因为在C中,struct struct和typedef名称在不同的名称空间中但是它不能用C ++编译( extern “C” { #include “MyAST.h” } ),因为typedef和struct names在同一名称空间中。 conflicting declaration ‘typedef struct MyAST* MyAST’ 我想我注定要将struct def移到标题中并放弃使用该技术,但我真的不想(这个成语用在很多代码中,有些是我的,有些不是)并认为我是在这里查看是否有人有任何见解。 PS:如果你不知道这个成语,它可以让你将结构定义保存在实现C文件中,然后接口的用户( MyAST.h )无法访问结构,他们必须在实现中使用你的函数。

sdcc不接受代码

我有SDCC的问题。 我的代码(我试图从另一个编译器移植)使用具有灵活数组成员的结构。 但是,当我尝试编译以下代码时: /** header of string list */ typedef struct { int nCount; int nMemUsed; int nMemAvail; } STRLIST_HEADER; /** string list entry data type */ typedef struct { int nLen; char str[]; } STRLIST_ENTRY; /** string list data type */ typedef struct { STRLIST_HEADER header; STRLIST_ENTRY entry[]; } STRLIST; // By the way, […]

使用extern“C”包装C lib,除了内部C ++包括

我有一个C库,我需要在C ++代码中使用,所以我需要用extern “C”块包装整个lib。 问题是该库似乎包含一个C ++编译的代码,因此包装整个lib也会包装该C ++头。 在lib.h里面我只包含了我要公开的所有内部头文件,如下所示: #ifndef LIB_H #define LIB_H #include “lib_foo.h” #include “lib_bar.h” #include “lib_baz.h” #endif 因此客户端只需要包含lib.h即可使用lib。 在我的第一次尝试中,我做到了这一点: #ifndef LIB_H #define LIB_H extern “C” { #include “lib_foo.h” #include “lib_bar.h” #include “lib_baz.h” } #endif 但是当我在already_compiled_c++.h执行任何函数时,我得到一个符号查找错误。 如何避免在already_compiled_c++.h头文件中应用extern “C” ? 编辑: 解决了。 这不是使用extern “C”的问题,将编译的c ++库与gyp正确链接是一个问题: 在node-sqlite3中使用Gyp中的共享库

LLVM和GCC,不同的输出相同的代码

这是一个示例代码,仅用于显示LLVM编译器和GCC的不同输出。 我想知道为什么? 答案应该很简单,但我看不到它。 (Xcode 4.6.1) 代码: #include #define MAX(a,b) ( (a) > (b) ? (a) : (b) ) int increment() { static int i = 42; i += 5; printf(“increment returns %d\n”,i); return i; } int main( int argc, char ** argv ) { int x = 50; printf(“max of %d and %d is %d\n”, […]

从数据部分执行一段代码

我想获取一段代码,将其复制到全局数组中并从那里执行。 换句话说,我试图将一堆指令从代码部分复制到数据部分,然后设置程序计数器以继续从数据部分执行程序。 这是我的代码: #include #include typedef void(*func)(); static void code_section_func() { printf(“hello”); } #define CODE_SIZE 73 // I verified this size in the disassembly of ‘code_section_func’ static long long data[(CODE_SIZE-1)/sizeof(long long)+1]; // I am using ‘long long’ in order to obtain the maximum alignment int main() { func data_section_func = (func)data; memcpy((void*)data_section_func,(void*)code_section_func,CODE_SIZE); data_section_func(); return 0; […]

为什么main在没有变量时初始化堆栈帧

为什么这个代码: #include “stdio.h” int main(void) { puts(“Hello, World!”); } 决定初始化堆栈帧? 这是汇编代码: .LC0: .string “Hello, World!” main: push rbp mov rbp, rsp mov edi, OFFSET FLAT:.LC0 call puts mov eax, 0 pop rbp ret 为什么编译器初始化一个堆栈帧只是为了以后它被销毁,而它是否曾经被使用过? 这肯定不会导致主函数外部的任何错误,因为我从不使用堆栈,所以我不会导致任何错误。 为什么这样编译?