首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

为什么printf在从Makefile调用时会有不同的行为?

printf在从Makefile调用时会有不同的行为,是因为Makefile中的命令是在Shell中执行的,而不是直接在C程序中执行。这导致了一些环境变量和特殊字符的差异,从而影响了printf的行为。

具体来说,当在Makefile中调用printf时,可能会遇到以下问题:

  1. 环境变量的差异:Makefile中的命令是在一个新的Shell子进程中执行的,这意味着它可能没有继承父进程中的所有环境变量。因此,如果printf依赖于某些环境变量,而这些变量在Makefile的上下文中未定义,那么printf的行为可能会受到影响。
  2. 特殊字符的转义:Makefile中的命令会对特殊字符进行转义处理,以确保它们被正确解释。这可能导致printf中的一些特殊字符(如转义序列)被错误地解释或转义,从而导致输出结果与预期不符。

为了解决这些问题,可以采取以下措施:

  1. 显式地传递环境变量:在Makefile中调用printf时,可以使用export命令显式地将所需的环境变量导出,以确保它们在子进程中可用。
  2. 使用双引号引用参数:在Makefile中调用printf时,建议使用双引号将参数引起来,以避免特殊字符的转义问题。例如:printf "%s\n" "Hello, World!"

需要注意的是,以上解决方案是一般性的建议,具体情况可能因环境和代码实现而异。在实际使用中,可以根据具体情况进行调试和调整。

腾讯云相关产品和产品介绍链接地址:

  • 腾讯云产品:https://cloud.tencent.com/product
  • 腾讯云云原生产品:https://cloud.tencent.com/solution/cloud-native
  • 腾讯云音视频处理产品:https://cloud.tencent.com/solution/media
  • 腾讯云人工智能产品:https://cloud.tencent.com/solution/ai
  • 腾讯云物联网产品:https://cloud.tencent.com/solution/iot
  • 腾讯云移动开发产品:https://cloud.tencent.com/solution/mobile
  • 腾讯云存储产品:https://cloud.tencent.com/solution/storage
  • 腾讯云区块链产品:https://cloud.tencent.com/solution/blockchain
  • 腾讯云元宇宙产品:https://cloud.tencent.com/solution/metaverse
页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

极简shell制作

文件 和 C源文件: touch makefile#或者 Makefile touch myshell.c#其他名字都行,后缀是.c即可   因为我们构建是C语言项目,所以makefile内文件配置也很简单...自定义Shell编写 ✈️命令行解释器   首先,我们根据常用shell行为分析:   常用 shell 都有叫做 命令行解释器 东西(上图红框),而命令行解释器其实就是 由不同字符串所构成 ,...,有时候有一个选项,有时候没有选项,而shell会根据不同选项来执行不同动作。   ...其中只有cd 是不带空格,其行为是:   如果cd 不带任何选项,那么其行为就是 切换到家目录。...export命令处理   当我们在 自定义 Shell 中导入一个新环境变量,也是由子进程进行程序替换完成这件事,所以,当我们使用hell进行env,是看不到导入环境变量:   所以,export

13610

【Linux】进程程序替换

想要弄明白为什么要有进程程序替换,我们首先要知道父进程创建子进程目的是什么?想要子进程完成什么样任务? 想让子进程执行父进程代码一部分。...程序替换原理就是:把物理内存中原来代码和数据替换成目标程序代码和数据,也就是说:调用execl之后代码和数据都被替换掉了,有可能还要发生映射关系改变。...2.多进程 在理解单进程程序替换基础上,多进程程序替换就容易理解了。 我们先要达成一个共识:写拷贝这种机制,不仅仅是对数据,对代码也有写拷贝策略。...详解如下: 1.execlp 程序替换类函数函数名称共同部分为:exec。然后后面再加不同字母,显然这些字母代表着不同含义: l:list。表示将参数逐个传入。 p:path。...四.如何利用程序替换函数调用自己写程序 我们自己写程序也是可执行程序,理论上也是可以使用程序替换函数进程程序替换

9810
  • 【linux】进度条

    因为接下来代码调用 sleep(3) 而没有刷新缓冲区,所以在大多数情况下,您在终端上可能看不到立即输出。 直到程序退出或缓冲区被手动刷新,“hello Makefile!” 内容才会显示。...如果你希望在没有换行符情况下立即刷新输出缓冲区,可以在 printf调用 fflush(stdout): 修改后代码块2: #include #include <unistd.h...终端显示: hello Makefile! (暂停3秒钟) 带有换行符 \n printf 在行缓冲模式下会立即刷新到终端。...没有换行符 printf 可能不会立即刷新缓冲区,需要手动调用 fflush(stdout) 。...这些现象主要源于终端缓冲机制行为,在不同开发和调试环境中(特别是高速输出场景下)理解这些机制尤其有用。

    7110

    【Linux】探索进程控制奥秘,解锁高效实战技巧

    1.进程创建 1.1字符串常量为什么不可以修改? 这里为什么编译不通过? 因为字符串具有常量属性,字符常量不可被修改。这里问题是字符串为什么会有常量属性呢?...pid 1.5.写拷贝: 为什么要用拷贝形式,父进程直接将资源给子进程不就行了吗?...页表不仅仅有将虚拟地址转换为物理内存,还会有权限位 1.7.fork常规用法 一个父进程希望复制自己,使父子进程同时执行不同代码段。例如,父进程等待客户端请求,生成子进程来处理请求。...一个进程要执行一个不同程序。...因为进程具有独立性,我们将子进程进行替换,发生写拷贝,不会影响父进程 一次想生成两个可执行文件,就需要这么写,不然makefile默认值生成第一条指令!

    4910

    盛弘电气2021秋招笔试题

    笔试时间:2020.09.16,60分钟 宣讲会后直接笔试,若通过会有两轮面试,7-15天出结果。 题型:简答题8道,每题5分,共40分。编程题4道,每题15分,共60分。...1、 insmod module 2、 驱动module初始化(初始化结束后即进入“潜伏”状态,直到有系统调用) 3、 当操作设备,即有系统调用时,调用驱动module提供各个服务函数 4、 rmmod...为什么?...=%lf",n,sum); printf("\n"); return 0; } 2、请写一个单例模式(C++)。...3、是否对Linux下编译有了解,如果有请写一个编译命令(编译文件为:Hello.cpp),是否对makefile有了解,如果有请写一个简单Makefile脚本。 4、写一个代码,产生一个线程。

    1.2K30

    Linux:进程控制(二.详细讲解进程程序替换)

    通过地址空间替换,进程可以在运行时动态地加载并执行不同程序,从而实现灵活程序执行和管理。 exec 函数族:exec 函数族是一组系统调用,用于执行程序替换操作。...1.2原理 当进程调用一种exec函数,该进程用户空间代码和数据完全被新程序替换 替换完成后,控制权将转移到新程序入口点,开始执行新程序代码。...因为被替换掉了,这也是什么代码没有输出execl end原因了 exec函数调用成功,那么它实际上不会有返回值;调用失败,它会返回-1 exec函数不会创建新进程。...把数据从一个硬件搬到另一个硬件,只有操作系统能做 2.多进程程序替换 我们可以创建一个子进程,由子进程来进行程序替换,父进程来等待结果就可以。为什么?...,而不会因为同名文件或目录存在而跳过这些命令 运行 make 命令(没有指定具体目标),make 会首先查找 Makefile第一个目标,并尝试构建它。

    19710

    Linux设备驱动程序(二)——建立和运行模块

    printk 函数在 Linux 内核中定义并且对模块可用;它与标准 C 库函数 printf 行为相似。...一旦发现内核源码树,makefile 调用 default: 目标,来运行第 2 个 make 命令( 在 makefile 里参数化成 $(MAKE)) 象前面描述过一样来调用内核建立系统,在第 2...一个应用程序可以调用它没有定义函数:连接阶段使用合适函数库解决了外部引用。 printf 是一个这种可调用函数并且在 libc 里面定义。...且这种保护功能分为不同级别,当 cpu 中存在多个级别,unix 通常使用最高级和最低级,即:超级用户级和用户级,也即内核空间和用户空间。...更不好是,如果驱动已被交换到硬盘,响应时间会长到不可接受,使用 mlock 系统调用可能会有帮助,但是常常你将需要锁住许多内存页,因为一个用户空间程序依赖大量库代码,mlock 也限制在授权用户上

    84641

    【Linux修炼】9.环境变量

    环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境一些参数。 2. 为什么会有环境变量?...而环境变量具有全局属性,也就是说环境变量本来就是定义给bash,但是bash环境变量会被子进程继承下去(为什么要继承,为了不同应用场景 ——让bash帮我找指令路径,身份认证),也就是说子进程能够使用...预备工作: 在演示之前,我们要对其进行准备工作,也就是设置一下Makefile以及程序代码: Makefile: 在这里,我们可以通过脚本语言来改变之前代码风格,即第一个后@代表生成mycmd...执行: 我们可以发现,所打印结果,就是对应命令行中命令以及选项,因此我们也知道了为什么叫做命令行参数: 但main函数是程序入口,那么是谁调用了main函数呢?...事实上这些都是shell和操作系统所做出行为。因此有的编译器中没有并不是真的没有,而是隐藏在相关位置,操作系统同样会通过命令行参数去通过命令调用这个程序。

    1.2K00

    手把手教你写一个 Makefile 文件

    第一间看干货文章 1 如果我们是在Linux下开发,那Makefile肯定要知道,不懂Makefile,面对较大工程项目的时候就会比较麻烦,懂得利用开发工具将会大大提高我们开发效率,也可以说Makefile...一、了解什么是 Makefile 一个大型工程中源文件不计其数,各个功能或者模块分别放在不同目录下,手动敲命令去编译就带来很大麻烦,那么Makefile可以定义一系列编译规则,哪些文件需要先编译...可见,Makefile都成为了一种在工程方面的编译方法。当然,不同产商make各不相同,也有不同语法,但其本质都是在 “文件依赖性” 上做文章。...如果执行make出现如下信息,那就是你代码没有修改过,Makefile拒绝你请求: 这里还会有一种情况就是如果只修改过其中一个文件,那么重新编译就可以看到只编译修改那个文件,没有编译其他未修改文件...会试图去自动推导产生这些目标的依赖和生成命令,这个行为就是隐含规则自动推导。

    1.6K10

    makefile从入门到放弃——博主吐血整理笔记

    文件: $ make #默认生成第一个文件 $ make '目标名'#选择性编译 当工程中文件名和makefile目标重名,就会有伪目标。...其与C/C++所不同是,你可以在Makefile中改变其值。在makefile中,变量可以使用在“目标”,“依赖目标”, “命令”或是Makefile其它部分中。...,但是不执行这些命令 -p 显示make变量数据库隐含规则 -s 在执行命令不显示命令 -w 如果执行make在执行过程中改变目录,打印当前目录名 当然makefile也可以像C语言一样调用其他...makefileVPATH VPATH:虚路径 在一些大工程中,有大量源文件,我们通常做法是把许多源文件分类,并且存放在不同目录下。...如果执行总控 Makefile ,make 命令带有参数或者在上层 Makefile 中定义了这个变量,那么 MAKEFLAGS 变量值将会是 make 命令传递参数,并且会传递到下层 Makefile

    1.7K20

    Makefile从入门到上手

    make 会自动寻找规则里需要材料文件,执行规则下面的行为生成规则中目标。...比如,待删除文件集合是 5 个,已经手动删除了 1 个,就只剩下 4 个,然而删除命令里面还是 5 个集合,就会有删除不存在文件问题,不加这 - ,就会报错,告诉你有一个文件找不到。...还有一个扩展就是,编译参数, -g,-Wall 这些,可以放在 makefile 里面 修改后 makefile 如下: Makefile 第十版 src = $(wildcard *.c) #...可以看到 A 值为空,B 值为 abc,因为 A 为即时变量,在定义即确定,所以为空 修改 Makefile 将 C 赋值放在最后: A := $(C) B = $(C) #C = abc...为函数参数,参数间以逗号 , 分隔,而函数名和参数之间以“空格”分隔。函数调用以 $ 开头,以圆括号或花括号把函数名和参数括起。

    39330

    【在Linux世界中追寻伟大One Piece】信号捕捉|阻塞信号

    被阻塞信号产生将保持在未决状态,直到进程解除对此信号阻塞,才执行递达动作。 注意,阻塞和忽略是不同,只要信号被阻塞就不会递达,而忽略是在递达之后可选一种处理动作。...内核决定返回用户态后不是恢复main函数上下文继续执行,而是执行sighandler函数,sighandler和main函数使用不同堆栈空间,它们之间不存在调用和被调用关系,是两个独立控制流程。...如果在调用信号处理函数,除了当前信号被自动屏蔽之外,还希望自动屏蔽另外一些信号,则用sa_mask字段说明这些需要额外屏蔽信号,当信号处理函数返回自动恢复原来信号屏蔽字。...像上例这样,insert函数被不同控制流程调用,有可能在第一次调用还没返回就再次进入该函数,这称为重入,insert函数访问一个全局链表,有可能因为重入而造成错乱,像这样函数称为不可重入函数,反之...想一下,为什么两个不同控制流程调用同一个函数,访问它同一个局部变量或参数就不会造成错乱?

    7810

    【Linux修炼】11.进程创建、终止、等待、程序替换

    任意地方调用 exit(code)退出 code为退出码,下面就演示一下: 结果显而易见,当我们查看这个进程是如何结束,直接观察退出码: 此外,在函数内部exit,进程也会直接结束,函数也不会有返回值...但是我们发现第一个printf打印出来了,但是execl后面的printf却没有打印出来,这是为什么呢?...通过下面理解: 4.2 理解原理(是什么、为什么、怎么办) 当我们执行代码,就会创建进程地址空间与物理内存磁盘之间形成映射关系,当执行上面的代码就是这样,执行第一个printf会照常打印,到了execl...函数,就会发生进程程序替换,也就是说,我们所编写代码会被我们调用execl对应磁盘内部代码覆盖,即将指定程序代码和数据覆盖自己代码和数据,执行这个新代码和数据,所以我们明白了为什么execl...而exec系列函数调用成功是没有返回值,也不需要返回值,因为进程被替换之候原本代码就没有意义了,即便返回了一个值,也不会有什么作用,还会有额外开销。

    6.2K00

    6_Makefile与GCC

    其中: ​ gcc是在x86架构指令用。 ​ arm-linux- gcc是RSIC(精简指令集)ARM架构上面使用。 ​ 他们会把源程序编译出不同汇编指令然后生成不同平台可执行文件。...("%d ask\n",100); return 0; } 你会发现头文件被展开和printf函数中调用HUNDRED这个宏被展开。 ​...注意:在命令行中,静态库夹在库必须位于调用该库目标文件之后。 6.2.2.4 代码优化选项 ​ gcc提供几种不同级别的代码优化方案,分别是0,1,2,3和s级,用-Olevel选项表示。.../output 20 40 6.4 Makefile引入及规则 6.4.1 为什么需要Makefile? ​ 在上一章节对GCC编译器描述,以及如何进行C源程序编译。...为什么clean下命令没有被执行?这是因为Makefile中定义只执行命令目标与工作目录下实际文件出现名字冲突。

    3.6K10

    Makefile学习1

    有的规则可能无目标依赖,仅仅是为了实现某种操作,如下面的clean命令: clean: rm -f a.out hello.o 使用make clean命令清理编译文件,会调用这个规则中命令...默认目标 一个Makefile文件里通常会有多个目标,一般会选择第一个作为默认目标。 正常情况下,当你想编译生成a.out,要使用make a.out命令。...而val_b则不同,因为是延迟展开变量,所以,当make解析到 = 符号,并没有立即把(b)值赋值给val_b,而是在运行echo命令才对其展开,因为此时b值已经是20,所以(val_b)值是...当一个追加变量在定义使用了override,后续对它值进行追加,也需要使用带有override指示符追加方式。否则对此变量值追加不会有效。...递归执行 在实际工程项目中,各个源文件通常存放在各个不同目录中,make在编译工程项目,会依次遍历各个不同子目录,编译每个子目录下源文件。

    38510

    【Linux】--- Linux编译器-gccg++、调试器-gdb、项目自动化构建工具-makeMakefile 使用

    那么为什么会有这些过程呢? 这就要说到编程语言历史了。最初计算机只能处理二进制,二进制是处理器“母语”。这叫“机器语言”或者“机器码”。...那为什么不直接将c语言转为二进制目标文件呢?因为前人已经写好了汇编编译器,我们只需站在巨人肩膀上,再将高级语言转为较简单汇编代码即可。 那么如何形成第一个汇编写汇编编译器呢?...1.3 链接 – 动静态链接特点及区别 我们C程序中,并没有定义"printf"函数实现,且在预编译中包含"stdio.h"中也只有该函数声明,而没有定义函数实现,那么,是在哪里实"printf..."printf"了,而这也就是链接作用。...make程序会读取makefile文件中数据,然后根据规则调用编译器,汇编器,链接器产生最后输出。 Makefile里主要包含了五个东西:显式规则、隐晦规则、变量定义、文件指示和注释。1.

    38620

    C语言令人抓狂一面——全局变量

    而变量a都是弱符号,所以只选择一个(按照目标文件链接顺序)。 事实上,这种规则是C语言里一个大坑,编译器对这种全局变量多重定义“纵容”很可能会无端修改某个变量,导致程序不确定行为。...个人认为可以这样解释,fork创建新进程,子进程获得了父进程上下文“镜像”(自然包括全局变量),虚拟地址相同但属于不同进程空间,而且此时真正映射物理地址中只有一份拷贝,所以b值是相同(都是2)...随后子进程对b改写,触发了操作系统**写拷贝(copy on write)**机制,这时物理内存中才产生真正两份拷贝,分别映射到不同进程空间虚拟地址上,但虚拟地址值本身仍然不变,这对于应用程序来说是透明...还有一点值得注意,这个示例编译没有出现第一个示例警告,即对变量bsizeof决议,笔者也不知道为什么,或许是GCC一个bug?...眼尖读者发现,这次foo.c是作为动态链接库运行时加载,当t1第一次调用t2,libfoo.so还未加载,一旦调用了foo函数,b立马中弹,而且c地址居然还相邻着b,这使得c一同中弹了。

    81110

    Linux 内核编译 LOCALVERSION 配置(分析内核版本号自动添加+号)

    1 问题发现 编译主线 kernel 版本时候发现, 内核版本编译成功后生成版本号变成了 "x.y.z+", 为什么后面会多一个加号呢?...都会出现 + 后真的感觉很郁闷, 强迫症我真的受不了. 2 原因分析 问题必然出现在 linux 构建过程中版本控制这一块, 既然是在构建过程中添加, 那我们就可以从 Makefile 中发现一些端倪...这些是我们内核版本版本号, 生成出来版本号理论上不应带 + 号, 但为什么带 + 号呢....使用 scripts/setlocalversion 工具来生成 include/config/kernel.release. “+” 号就是在调用这个脚本添加....= "set", 那么调用 scm_version --short 会在最后添加一个 + 号. 原来如此, 加号是这样加上去.

    3.6K20
    领券