What's New in LLVM 9

ubuntu18.04安装llvm-9 clang-9 低版本的ubuntu只能采用编译安装的方式,高版本的ubuntu可以采用如下方式安装 echo deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-4.0 main\ >> /etc/apt/sources.list.d/llvm.list echo deb-src http://apt.llvm.org/xenial/ llvm-toolchain-xenial-4.0 main\ >> /etc/apt/ 阅读详情

What’s New in LLVM 9


这绝不仅仅是一篇 WWDC 2017 Session 411 学习笔记。除了有关 LLVM 9.0 的新特性之外,还有关于静态分析器和 Clang 5 Objective-C ARC 的一点看法和经验。
我觉得 LLVM 9 的亮点如下:

  1. 支持 Objective-C API 可用性检查
  2. 新增一些对隐患代码的静态分析检查和 warning
  3. 更快的 LTO,使其可以真正使用

API Availability Checking for Objective-C

在低版本系统上调用高版本 SDK 的 API 会引发 crash,所以在兼容多版本系统时需要谨慎判断系统版本,然后使用对应的 API。这些在运行时才能生效的代码很容易编写出错,而且需要测试人员付出很大工作量来覆盖到各个版本的系统。检查类、实例方法、类方法等是否可用时需要写的代码也不同,很蛋疼呦。
Swift 3 加入了 #available 语法来检查 API 是否可用,在编译阶段就可以发现哪里漏掉了 API 可用性检查。如今,Objective-C 也有这项功能啦。

Objective-C

假设加入 App 支持的最低版本是 iOS 10,但是直接调用了 iOS 11 的 API,那么编译器会告警,提醒开发者某个 API 只能用于较新版本的系统上。这时需要通过 @available 语法来判断平台和版本:

if(@available(iOS 11, *)) {
    // iOS 11 以上以及其他所有平台
}
  • 相当于通配符,代表所有其他平台都可用。

说完了如何检查 API 可用性后,再来谈谈声明 API 可用性的问题:

- (void)foo API_AVAILABLE(ios(11.0));

上面的代码声明了调用 foo 方法需要 iOS 11 以上,而 foo 方法内部的实现中调用 iOS 11 的 API 时无需再用 @available 检查。
声明一个类的可用性也很简单,并且无需给类中的每个方法再次声明可用性,只需要用到 API_AVAILABLE 宏:

API_AVAILABLE(ios(11.0))
@interface MyClassForiOS11OrNewer : NSObject
- (void)foo;
@end

其实类似的有关 API 兼容版本的宏还有好几个:

API_DEPRECATED()
API_UNAVAILABLE()
API_DEPRECATED_WITH_REPLACEMENT()

C & C++

如果是想在 C 或 C++ 中查询 API 的可用性,可以使用 LLVM 新加的 __builtin_available() 函数:

if (__builtin_available(iOS 11, macOS 10.13, *)) {
    // iOS 11 以上或 macOS 10.13 以上平台,以及其他所有平台
}

在 C 或 C++ 中使用 API_AVAILABLE 宏之前需要引入头文件

#include <os/availability.h>
class API_AVAILABLE(ios(11.0)) MyClassForiOS11OrNewer;

适用范围

对于旧工程,LLVM 只会对新的 API 进行告警(包含 iOS 11,tvOS 11,macOS 10.13,watchOS 4 以上)。旧的 API 不会被编译器告警,所以不用担心旧项目中已有的代码会产生一大片 warning,只需在采用新 API 的时候加上 @available 或 API_AVAILABLE。也可以选择在 Build Settings 中设置 Unguarded availability 为 YES(All Versions) 来检查所有的 API。Xcode 9 新建工程 Unguarded availability 项默认为 YES(All Versions)。

Static Analyzer Checks

除了在 Xcode->Product->Analyze 中开启静态分析检查外,也可以在 Build 过程中进行静态分析检查。只需在编译设置中将 Analyse During ‘Build’ 设为 YES。
苹果补充了一些检查项,看了下还都是一不留神就容易犯或者根本没注意到的细节。

比较 NSNumber

稍有经验的老司机都懂得 NSNumber 不能直接跟 raw value 直接比较,毕竟前者是类的实例对象,后者是基本类型。然而还是有人会弄错:

NSNumber *count = @0;
NSNumber *check = @YES;
if (count > 0) {
  NSLog(@"肯定会进到这里,因为 count 不为 nil");
}
if (check) {
  NSLog(@"肯定会进到这里,因为 check 不为 nil");
}

现在 LLVM 可以检查出这种情况,也可以关闭这项检查:在编译设置中将 Suspicious Conversions of NSNumber and CFNumberRef 设为 NO。

dispatch_once()

Xcode 的 code snippet 很好用,我觉得正常人不会把 dispatch_once() 写错吧。

static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
   foo();
});

onceToken 只能是全局变量或静态变量,使得指针地址的唯一性保证了 foo() 只执行一次。但总有奇葩把 onceToken 声明成成员变量,使得指针地址可能会重复,无法保证线程安全地只执行一次。而现在 LLVM 可以检查出这种不规范的使用方式。

当然,想实现线程安全地只执行一次方法,也可以通过加锁和判断标志位的方式来实现。

NSMutable 类型的属性使用 copy 内存管理语义

@property (nonatomic, copy) NSMutableArray *array;

内存管理语义帮开发者自动合成了 set 方法的实现,但是当 copy 应用到了 NSMutable 系列的类上,就会产生问题。因为我们想要的是把新的值 mutableCopy 后赋值给属性,然而内存管理语义中只有 copy 却没有 mutableCopy。而现在 LLVM 可以检查出这种情况。

重写 set 方法可以解决此问题:

- (void)setArray:(NSMutableArray *)array
{
    _array = [array mutableCopy];
}

一些建议

静态分析能做到在编译阶段发现一些程序员容易疏忽的地方,它只能检查特定场景下的一些被认为不符合规范的行为。也就是说它维护了一个 List,编译的时候一项一项检查是否合符规范,但是这个 List 之外的行为并不能被检查出来,这也就是为什么 LLVM 每年都在向这个 List 新增内容。这个 List 包含了程序员容易犯的代码问题,并且这些问题暗涵很严重的逻辑错误。

  1. 随着 Check List 的不断膨胀,静态分析耗时会增加,对于大中型项目,我并不建议开启每次编译时都进行静态分析检查。建议在每个版本测试阶段定期做静态分析检查。
  2. 不要过于相信静态分析检查。首先它会漏检,Check List 之外的情况根本检查不出来。如果将一些 API 包含在宏定义中或者封装在 C 函数中调用,导致语法复杂,静态分析甚至还会误报。(我曾经碰见过几次静态分析检查出 MRC 下一些内存泄露,但其实间接调用了 autorelease 的,根本不会泄露,改为直接调用 autorelease 就 OK 了)
  3. 程序员自身应该有一份 Check List,在平时变成变成过程中不断约束自己。比如判断 NSString 是否有内容时直接看 length 是否大于 0,而不是判断是否为 nil 或 @”“。这跟打游戏是否有意识差不多,写代码也要有『意识流』。

New Warnings

Xcode 9 的 LLVM 又新增了一百多个 error 和 warning,然而大多数程序员还不是照样忽视 warning 么?可以在编译设置中将 warning 升级成 error。如果是旧的工程,需要升级工程文件到 Xcode 9,然后才能看到这些新增的 warning 设置项。(点击工程->Editor->Validate Settings)

ARC 中的 Block 捕获参数

- (void)validateDictionary:(NSDictionary<NSString *, NSString *> *)dict error:(NSError **)error
{
    [dict enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, NSString * _Nonnull obj, BOOL * _Nonnull stop) {
        if (obj.length > 0) {
            if (error) {
                *error = [NSError errorWithDomain:@"FishDomain" code:0 userInfo:nil];
            }
        }
    }];
}

ARC 会将 (NSError *)error 这种 “out-parameter” 隐式修饰为 __autoreleasing,也就是其实会被转化成 (NSError __autoreleasing *)error。(PS:相关知识参考 Indirect parameters)

给 *error 赋值时,因为它被 __autoreleasing 修饰,所以 ARC 下的 Clang 会隐式调用 retain 和 autorelease。 PS: 相关知识参考 Semantics

而 enumerateKeysAndObjectsUsingBlock: 方法会在 @autoreleasepool 里面执行 Block,在迭代逻辑中这样做有助于减少内存峰值。

于是 *error 就在 Block 里提前被释放了。Xcode 9 会针对这种情况发出 warning:”Block captures an autoreleasing out-parameter, which may result in use-after-free bugs”。解决方案:”Declare the parameter strong or capture a block __strong variable to keep values alive across autorelease pools”

第一个解决方案简单地把参数 (NSError *)error 改成 (NSError *__strong )error,这要求调用方也使用 ARC。第二个解决方案是利用 __block 让 Block 捕获外部变量,默认是强引用:

- (void)validateDictionary:(NSDictionary<NSString *, NSString *> *)dict error:(NSError **)error
{
    __block NSError *strongError = nil;
    [dict enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, NSString * _Nonnull obj, BOOL * _Nonnull stop) {
        if (obj.length > 0) {
            strongError = [NSError errorWithDomain:@"FishDomain" code:0 userInfo:nil];
        }
    }];
    if (error) {
        *error = strongError;
    }
}

关于 Clang 隐式调用 retain 和 autorelease 更深入的细节如下:

Clang 5 中的 Objective-C ARC 方法家族

Objective-C 中有五大方法家族,每个家族都有自己的规矩:alloc/new/copy/mutableCopy 四个家族的方法返回的是 “a retainable object pointer”,而 init 家族方法要求必须是实例方法,必须返回 Objective-C 对象。
把一个方法划归到某个方法家族有两种方式:

  1. 按照命名惯例划分方法家族
  2. 使用 attribute((objc_method_family( somefamily ))) 直接指定

如果某个方法不遵循所在家族的规矩,会影响到内存管理,造成内存泄露等后果。(PS:如果是使用第二种方式把不守规矩的方法划归到家族,Clang 会报错。)

ARC 下遵循一套内存管理原则:

  1. alloc/new/copy/mutableCopy 家族的方法创建的对象是自己持有的,会被 Clang 隐式标记为 attribute((ns_returns_retained))。等效于 Foundation 中的宏 NS_RETURNS_RETAINED
  2. init 家族会被 Clang 隐式标记为 attribute((ns_consumes_self)) 和 attribute((ns_returns_retained)),用 NS_REPLACES_RECEIVER 宏也是等效的。
    不属于任何方法家族的方法会被 Clang 隐式标记为 attribute((ns_returns_not_retained)),等效于 Foundation 中的宏 NS_RETURNS_NOT_RETAINED。

一般情况下 Clang 会帮我们做这些事情,不必给方法声明手动标记这些属性。而且 Clang 会对最终生成的汇编指令进行优化,去掉多余的 retain 和 autorelease。

ARC 会视情况在调用方法时可能会添加 retain,在方法内部返回时可能会添加 autorelease,经过优化后很可能会抵消。

attribute 其实并不是 Objective-C 的语法,而是 Clang 的属性。有关 Clang 的各种属性定义,请查看 Attributes in Clang

探索方法返回值内存管理的奥秘

先做两种情况的实验,查看汇编代码,并总结:方法为 alloc/new/copy/mutableCopy 家族或方法声明使用 NS_RETURNS_RETAINED

- (id)newFoo;
- (id)foo NS_RETURNS_RETAINED;

- (id)newFoo
{
    return [NSObject new];
}
- (id)foo
{
    return [NSObject new];
}

debug 时从汇编中可以看出:调用方无操作,方法返回时无操作。这显然是优化后的结果。虽然两种方式都能达到优化效果,但更推荐采用让方法加入方法家族,而不是直接使用 NS_RETURNS_RETAINED 宏。

普通方法

- (id)foo;

- (id)foo
{
    return [NSObject new];
}

debug 时从汇编中可以看出:调用方调用 objc_retainAutoreleasedReturnValue(),方法返回时调用 objc_autoreleaseReturnValue()(如果返回值没有赋值给变量,会调用 objc_unsafeClaimAutoreleasedReturnValue())。

优化过程及原理

objc_retainAutoreleasedReturnValue(value) 会尝试将之前调用 objc_autoreleaseReturnValue(value) 时传入参数 value 的所有权(retain count)传递过来。如果没有在 value 上调用过 objc_autoreleaseReturnValue(value),那就调用 retain。具体原理通过查看 Objective-C 源码可以得出(我列举的是 objc-709):

objc_autoreleaseReturnValue() 试图优化流程,如果上一层调用方会调用 objc_retainAutoreleasedReturnValue() 则直接返回参数,否则调用 autorelease:

id 
objc_autoreleaseReturnValue(id obj)
{
    // ReturnAtPlus1 表示倾向直接把对象返回,这样就不需要调用 objc_autorelease(),优化性能
    if (prepareOptimizedReturn(ReturnAtPlus1)) return obj;

    return objc_autorelease(obj);
}

static ALWAYS_INLINE bool 
prepareOptimizedReturn(ReturnDisposition disposition)
{
    assert(getReturnDisposition() == ReturnAtPlus0);
    // __builtin_return_address(0) 获取当前函数返回地址,传入 callerAcceptsOptimizedReturn 判断调用方是否紧接着调用了 objc_retainAutoreleasedReturnValue 或者 objc_unsafeClaimAutoreleasedReturnValue
    if (callerAcceptsOptimizedReturn(__builtin_return_address(0))) {
        // 将标志位 disposition 写入 TLS
        if (disposition) setReturnDisposition(disposition);
        return true;
    }

    return false;
}

static ALWAYS_INLINE void 
setReturnDisposition(ReturnDisposition disposition)
{// 向 TLS 中写入 Disposition
    tls_set_direct(RETURN_DISPOSITION_KEY, (void*)(uintptr_t)disposition);
}

static ALWAYS_INLINE ReturnDisposition 
getReturnDisposition()
{// 从 TLS 中读取 Disposition
    return (ReturnDisposition)(uintptr_t)tls_get_direct(RETURN_DISPOSITION_KEY);
}

callerAcceptsOptimizedReturn() 函数在不同架构的 CPU 上实现也是不一样的,这是因为不同架构 CPU 的对齐方式不同,偏移量也不同。比如在 arm64 上由于指令对齐方式较好,只需判断函数返回的地址指向的值是不是 0xaa1d03fd 即可;而在 x86_64 平台上则要用一大坨代码来判断。有兴趣的可以查看 objc-object.h 文件。

objc_retainAutoreleasedReturnValue() 试图查看是否已优化过并直接返回参数,否则 retain:

id
objc_retainAutoreleasedReturnValue(id obj)
{   // 如果之前 objc_autoreleaseReturnValue() 存入的标志位为 ReturnAtPlus1,则直接返回对象,无需调用 objc_retain(),优化性能
    if (acceptOptimizedReturn() == ReturnAtPlus1) return obj;

    return objc_retain(obj);
}

// 负责从 TLS 中取标志位 ReturnDisposition,然后将其重置
static ALWAYS_INLINE ReturnDisposition 
acceptOptimizedReturn()
{
    ReturnDisposition disposition = getReturnDisposition();
    setReturnDisposition(ReturnAtPlus0);  // reset to the unoptimized state
    return disposition;
}

TLS 全称为 Thread Local Storage,是每个线程专有的键值存储。在某个线程上的函数调用栈上相邻两个函数对 TLS 进行了存取,这中间肯定不会有别的程序『插手』。所以 getReturnDisposition() 和 setReturnDisposition() 的实现比较简单,不需要判断考虑是针对哪个对象的 Disposition 进行存取,因为当前线程上下文中只处理唯一的对象,保证不会乱掉。

无参数函数的声明

如果函数没有参数,需要用 void 显式声明。否则可能调用方会传入其他类型和数量的参数,在运行时引发 crash。如果用 void 显式声明,在编译阶段就会产生 error。

int foo() // warning:This function declaration is not a prototype
int foo(void) // OK

C++ Refactoring

对于一个带有 C++ 或 Objective-C++ 代码的工程来说,想重命名某个类名真的是艰难,Xcode 会提示不支持 C++!现在,各种操作也支持 C++ 咯:

LLVM 的重构代码功能极大节省了开发者的时间。

Features from C++17

其实这些都是 C++17 的新特性罢了,LLVM 9.0 积极响应支持。可以在编译选项 C++ Language Dialect 中选择使用的 C++ 标准库。GNU++17 比 C++17 多了语言扩展。

Structured Binding

解析 Tuple 可以一句搞定了:

std::tuple<int, double, char> compute();
void run() {
    auto [a, b, c] = compute();
}

甚至也可以解析类似 tuple 的类型:

struct Point { double x; double y; double z; };
Point computeMidPoint(Point p1, Point p2);
...
auto [x, y, z] = computeMidPoint(src, dest);

更多内容详见 C++17 的 Stuctured Binding。

在条件判断语句中声明初始化变量

在判断某个条件之前,可能会产生一些中间变量,如果变量名与外界的有冲突,还会造成一些影响。所以需要一种只在条件判断语句范围内生效的局部变量,避免与无关逻辑代码有冲突:

if (auto a = getNumber(); a > 0) 
    foo();

...

a = 5; // error! a 只在上面的 if 作用域中有效。

constexpr if

以 if constexpr 开始的语句被称为 constexpr if 语句。– cppreference.com
举个栗子:advance 函数可以向前或向后迭代指定步数,但对于字符串和数组来说有更快的方式:无需一步步迭代,可以直接访问。但 advance 的参数是通用的,编译不通过:

传统解决方法是 Compile Time Dispatch:

C++17 的 constexpr if 可以一行搞定:

详见 constexpr if。

string_view

简单来说它是指向字符串的指针,但不会拷贝一份字符串。一旦指向的字符串被修改或者被释放了,string_view 的内容也会跟跟着变,毕竟是同一份内存。所以,虽然会优化性能,慎用。就像 OC 中的字符串和数组传递赋值时一般都 copy,string_view 相当于是 assign,搞不好野指针呢。

详见 string_view。

去年搞了个 LTO 和 增量 LTO,今年优化得编译速度更快了,于是建议我们打开 增量 LTO 啊:在编译选项中 Code Generation->Link-Time Optimization

其实我看了 2016 年的 What’s New in LLVM, LTO 确实占了很大篇幅,不过当时还不建议开启。经过一年的优化后算是修成正果了。

Windows下WSL2部署Hermes Agent全指南 Hermes Agent 是一个深度依赖 Linux 用户态环境、CUDA 加速与 POSIX 语义的本地 AI 助手框架,其核心组件(如 Ollama 调度器、Rust 向量化引擎、DeepSeek-R1 代理)在 Windows 原生环境中因缺乏 fork、epoll、/proc 文件系统及完整 CUDA ABI 兼容性而无法稳定运行。WSL2 凭借真实 Linux 内核、原生 GPU 支持(nvidia-smi 可见)和无缝 Windows 集成,成为当前唯一可行的部署底座。本指南聚焦 Ubuntu 阅读详情

相关推荐

LLVM(v9.0x64).7z

llvm v9.0 VS2017、x64、MT 编译。 无需VS运行库。

iOS 11 Xcode9开发 新特性学习 (警告篇)

最新版本SDK优化了开发体验,编译过程会提供更多提示警告,建议你修改。这些功能也可以自主选择用或者不用,当然,苹果喜欢你用他推荐的东西。。。 1 .@avalibale 语法,同步判断当前iOS系统是否满足需求。例如: if (@available(iOS 11, *)) { // >= 11 DLog(@"XXX1"); } else if (@av...

weixin_34290352的博客 351

LLVM-9.0.0-win64.zip

LLVM-9.0.0-win64压缩包。 LLVM是构架编译器(compiler)的框架系统,以C++编写而成,用于优化以任意程序语言编写的程序的编译时间(compile-time)、链接时间(link-time)、运行时间(run-time)以及空闲时间(idle-time),对开发者保持开放,并兼容已有脚本。

IOS 警告 收集

Semantic Warnings Warning Message -WCFString-literal input conversion stopped due to an input byte that does not belong to the input codeset UTF-8 -WNSObject-attri...

weixin_34283445的博客 384

决策树简介/PPT

最近给我们组新生讲了决策树的相关知识,以下是所做的PPT,参考了网络资源。

垃圾就应该待在垃圾桶里的博客 3795

别再瞎调参数了!分子动力学模拟新手必看的力场选择与验证实战指南

本文为分子动力学模拟新手提供力场选择与验证的实战指南,详细解析主流力场特性及适用场景,并通过水分子案例演示完整的验证流程。文章重点对比SPC/E、TIP3P和OPLS-AA三种力场在GROMACS中的表现,帮助读者避免常见参数调整误区,提升模拟准确性。

weixin_26934905的博客 425

What's New in LLVM9.0

What's New in LLVM By 杨萧玉  发表于 2017-07-17 文章目录 1. API Availability Checking for Objective-C 1.1. Objective-C1.2. C & C++1.3. 适用范围 2. Static Analyzer Checks 2.1. 比较 NSNumber2.2. 

mac的专栏 782

保姆级教程:用Python+OpenCV搞定Orbbec Gemini深度与彩色流对齐(附完整代码)

本文提供了一份详细的Orbbec Gemini深度与彩色流对齐教程,涵盖从环境配置到完整代码实现的每一步。通过解析深度流对齐原理,对比不同对齐模式,并提供工业级应用中的问题排查方法,帮助开发者快速掌握Orbbec Gemini相机的使用技巧。文章还包含进阶应用如点云生成与三维重建的实战代码。

weixin_29090917的博客 470

LLVM-9.0 学习者教程

LLVM-9.0 学习者教程 项目介绍 LLVM-9.0-Learner-Tutorial 是一个面向 LLVM(v9.0.0 或 v11.0.0)初学者的详细教程。该项目通过逐步讲解和详细的文档注释,记录了作者学习 LLVM 并最终完成一个完整项目的过程。教程的目标是帮助初学者理解和掌握 LLVM,特别是如何使用 LLVM 进行 FPGA 高层次综合(High-Level Synthesis, ...

gitblog_00450的博客 706

动态数据脱敏技术分析

在当前国内信息安全热潮中,数据脱敏作为数据安全的重要一环得到了业界的认可与重视。早在2012年,数据脱敏首次作为一个单独的魔力象限由Gartner发布,Gartner在2014年又提出了:按照数据使用场景,将数据脱敏分为静态数据脱敏(Static data masking-SDM )与动态数据脱敏(Dynamic data masking-DDM )。 可能有人望文生义,认为动态数据脱敏一定比静态数据脱敏高级。非也非也,静态or动态,取决于脱敏的使用场景,主要是以使用场景为由来选择合适的数据脱敏的模式。 本

美创科技的博客 4670

FreeCAD地下管道自动化建模实战:Python脚本从入门到导出OBJ

本文详细介绍了如何利用FreeCAD的Python API实现地下管道的自动化建模,从数据处理到模型导出OBJ格式的全流程。通过实战案例和代码示例,展示了圆形和矩形截面管道的创建方法,以及法兰连接等特殊处理技巧,大幅提升工程设计效率。

ff678的博客 248

Linux内核llvm,LLVM 9.0 发布,能够构建Linux x86_64内核

它比计划晚了将近一个月,但是LLVM 9.0和Clang 9.0 C/C++编译器以及这个开源编译器基础架构的相关子项目今天已经发布了。LLVM 9.0是一个令人兴奋的版本,它带来了使用LLVM/Clang 9.0构建主线Linux x86_64内核的能力,现在终于添加了“asm goto”支持。 AArch64的支持以前更好,但现在很久以来主线Clang 9.0编译器可以构建当前的Linux内核...

weixin_42494628的博客 497

Win11下Python脚本不执行?5分钟搞定PATH环境变量配置(VSCode终端实测)

本文针对Win11系统下VSCode终端中Python脚本执行无响应的问题,提供了详细的诊断与解决方案。核心在于正确配置PATH环境变量,通过图形化界面调整Python路径优先级,并分享了VSCode终端环境变量的刷新技巧,帮助开发者在5分钟内快速解决环境配置难题。

weixin_28358083的博客 384

ubuntu14.04安装llvm/clang 9.0预编译版本

1 ubuntu14.04安装llvm/clang 9.0预编译版本 下载llvm/clang prebuild: https://releases.llvm.org/download.html#9.0.0 https://download.youkuaiyun.com/download/wwchao2012/12391517 xz -d clang+llvm-9.0.0-x86_64-linux-gnu-u...

2426

使用Simulink进行无刷电机霍尔传感器信号处理电路的仿真

位置检测:霍尔传感器可以检测转子的位置,这对于实现无刷电机的电子换向至关重要。提高效率:通过准确的位置信息,可以优化电机的工作状态,提高效率和性能。通过上述步骤,我们简要介绍了如何基于Simulink实现无刷电机霍尔传感器信号处理电路的仿真。

MHD0815的博客 430

python:实现brutefore破解wifi(附完整源码)

python:实现brutefore破解wifi(附完整源码)

希望我的博客,能帮上你解决学习中工作中所遇到的问题 5706

How to add a dark theme to your Qt application

Dark themes are now available for Windows 10 and Mac and it is increasingly expected that desktop applications will offer a dark theme. Previously Qt support for dark themes was patchy. But I am happy to say that it now seems to work fine with Qt 5

weixin_42389294的博客 500

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

gcc的__builtin_函数介绍

GCC提供了一系列的builtin函数,可以实现一些简单快捷的功能来方便程序编写,另外,很多builtin函数可用来优化编译结果。这些函数以“__builtin_”作为函数名前缀。 很多C标准库函数都有与之对应的GCC builtin函数,例如strcpy()有对应的__builtin_strcpy()内建函数。 下面就介绍一些builtin函数及其作用: __builtin

落尘纷扰的专栏 4万+

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

iOS消除对应的警告!

在iOS开发过程中, 我们可能会碰到一些系统方法弃用, weak、循环引用、不能执行之类的警告。 有代码洁癖的孩子们很想消除他们, 今天就让我们来一次Fuck 警告!!首先学会基本的语句 #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" 这里写出现警告的代码#prag

贤_龍的博客 2355

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

C++ 高效位运算函数 之 __builtin_

刷题时偶然发现了该系列函数,感觉不错,分享下 1.__builtin_popcount(n)该函数时判断n的二进制中有多少个1int n = 15; //二进制为1111 cout<<__builtin_popcount(n)<<endl;//输出42.__builtin_parity(n)该函数是判断n的二进制中1的个数的奇偶性int n = 15;//二进制为1111 int m = 7;//1

nobleman 8582

__builtin函数总结

__builtin_clz(unsigned x); // count leading zeros __builtin_ctz(unsigned x); // count trailing zeros __builtin_popcount(unsigned x); // 1的个数 // ffs, parity 感觉没啥用。前者返回ctz+1,后者返回popcount&amp;1 // 另...

weixin_40676873的博客 4384

Robot Framework(十):BuiltIn中常用关键字(上)

目录 Log/Log Many Library Set Variable Set Suite Variable ​​​​​​​Catenate Create Dictionary ​​​​​​​Create List ​​​​​​​ BuiltIn是robot framework的标准库,提供了最通用和最常用的关键字,使用时会自动导入,下面我们只介绍使用频率较多的一些关键字,如果...

每天进步一点点 2686

Xcode 9

原文地址:点击打开链接 Xcode 9 Xcode 9兼容性 Xcode 9需要Mac运行macOS 10.12.6或更高版本。 Xcode 9包括iOS 11,WatchOS 4,macOS 10.13和tvOS 11的SDK。 Xcode 9.0 一般 新功能 在导航和助手编辑器中添加了用于确定文件对应物的

疯狐狸的博客 2881

ioS开发--Warning警告处理

去除警告的方法: #pragma clang diagnostic push #pragma clang diagnostic ignored"-Wunused-function" local void free_linkedlist(ll) linkedlist_data* ll; { free_datablock(ll->first_block); ll->first_blo

zzzzzdddddxxxxx的专栏 1万+

处理iOS开发中的各种警告

iOS开发中我们会遇到各种警告,包括第三方不再支持更新导致的警告,苹果一些过时方法的警告,其中尤其是ASIHttpRequest的不支持更新导致有很多的警告,所以我在这里做了罗列 Semantic Warnings WarningMessage -WCFString-literal input conversion stopped due to an inpu...

3163

LLVM的安装——从虚拟机到LLVM

2020年2月13日,好像是晴天也好像是阴天,管他什么天反正也没出门。晚上下楼扔垃圾,久违的微风拂面,恍然想起如今已经立春了,是春的温柔啊。啊,跑题了… 想要安装LLVM都需要准备些什么呢?需要安装:虚拟机、centos、gcc/g++、cmake。这里是我的安装步骤以及一些比较有参考性的文章。 准备步骤: 虚拟机的安装: 这个简单直接点点点就好没几步,装好后没有密钥的上网搜一个用就好,可以参...

CanaanLeeN的博客 1948
上一篇: GPUImage的图像形变设计(复杂形变部分)
下一篇: GPUImage源码解读(一)
Philm_iOS
博客等级 码龄8年 74粉丝 53原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值