`__isoc99_sscanf` is used regardless of `-std=c89 -pedantic`

I have this test file 1.c, and compile it with clang-11 -emit-llvm -std=c89 -pedantic -Wall -c -g -O0 -Xclang -disable-O0-optnone ./1.c, then use llvm-dis-11 to get 1.ll

#include<stdio.h>

int main(){
        int a;
        scanf("%d",&a);
        return 0;
}                                                                                                                                                                         

Here is the content of 1.ll, why @__isoc99_scanf exists after specify -std=c89 -pedantic?

; ModuleID = './1.bc'
source_filename = "./1.c"
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-pc-linux-gnu"

@.str = private unnamed_addr constant [3 x i8] c"%d\00", align 1

; Function Attrs: noinline nounwind uwtable
define dso_local i32 @main() #0 !dbg !7 {
  %1 = alloca i32, align 4
  %2 = alloca i32, align 4
  store i32 0, i32* %1, align 4
  call void @llvm.dbg.declare(metadata i32* %2, metadata !12, metadata !DIExpression()), !dbg !13
  %3 = call i32 (i8*, ...) @__isoc99_scanf(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str, i64 0, i64 0), i32* %2), !dbg !14
  ret i32 0, !dbg !15
}

As I understand it, that’s a glibc thing where the C99 variant was added to account for the addition of %a which was a GNU extension in C89. I believe you need to pass -std=c89 -D_GNU_SOURCE to get the C89 scanf call specifically, but this is a bit outside of my area of expertise as well.

1 Like

Thanks, that’s what I want