C言語

#include<stdio.h>せずにprintfを使う(C言語)

※注意 特に役に立つ情報は書いてないです

周知の通りC言語のinclude文は外部のファイルを文を書いた位置に埋め込むというただそれだけの命令です。
つまりは

#include<stdio.h>

はstdio.hというファイルを埋め込むという動作をします。

なんでこれが必要なのかというとC言語は使う関数を事前に宣言しないといけないという縛りがあるからなのですが、
追記:宣言しなくとも動作はする。しかしint以外を返せない。

とりあえずそれは置いといて前々から思っていたことがありました。

includeを使わなくても自分で宣言すればいいんじゃないか…?

include文がただファイルを埋め込んでいるだけというならばprintfを自分で宣言したところで動作は変わらないはず
ただ問題になるのはprintfをどう宣言したものかよくわからないというところです。

そこで思いついたのはコンパイラのプリプロセッサだけを通した結果を返す機能を使うという方法です。

やり方

print.c
#include<stdio.h>

みたいなファイルを用意する。
そして

$ clang -E print.c | grep printf
int fprintf(FILE * restrict, const char * restrict, ...) __attribute__((__format__ (__printf__, 2, 3)));
int printf(const char * restrict, ...) __attribute__((__format__ (__printf__, 1, 2)));
int sprintf(char * restrict, const char * restrict, ...) __attribute__((__format__ (__printf__, 2, 3))) ;
int vfprintf(FILE * restrict, const char * restrict, va_list) __attribute__((__format__ (__printf__, 2, 0)));
int vprintf(const char * restrict, va_list) __attribute__((__format__ (__printf__, 1, 0)));
int vsprintf(char * restrict, const char * restrict, va_list) __attribute__((__format__ (__printf__, 2, 0))) ;
int snprintf(char * restrict __str, size_t __size, const char * restrict __format, ...) __attribute__((__format__ (__printf__, 3, 4)));
int vsnprintf(char * restrict __str, size_t __size, const char * restrict __format, va_list) __attribute__((__format__ (__printf__, 3, 0)));
int dprintf(int, const char * restrict, ...) __attribute__((__format__ (__printf__, 2, 3))) __attribute__((availability(macosx,introduced=10.7)));
int vdprintf(int, const char * restrict, va_list) __attribute__((__format__ (__printf__, 2, 0))) __attribute__((availability(macosx,introduced=10.7)));
int asprintf(char ** restrict, const char * restrict, ...) __attribute__((__format__ (__printf__, 2, 3)));
int vasprintf(char ** restrict, const char * restrict, va_list) __attribute__((__format__ (__printf__, 2, 0)));
extern int __sprintf_chk (char * restrict, int, size_t,
extern int __snprintf_chk (char * restrict, size_t, int, size_t,
extern int __vsprintf_chk (char * restrict, int, size_t,
extern int __vsnprintf_chk (char * restrict, size_t, int, size_t,

あった!宣言が見つかった。

コード

int printf(const char * restrict, ...) __attribute__((__format__ (__printf__, 1, 2)));

int main() {
  printf("aaa");
  return 0;
}

やった!includeを使わずにprintfが使えたぞ!

終わり。