質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

2回答

1956閲覧

'va_start' used in function with fixed args

nyamagoyaki

総合スコア4

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2021/07/13 01:48

以下のソースコードで、'va_start' used in function with fixed args
と出てしまい、どうしたらいいのか分かりません。
書き方が古いそうなのですが、どう書き直せばよろしいでしょうか?
va_start(args, va_alist);
void lprintf(va_alist)
の引数を指定すればいいと思ったのですが、できませんでした。
C言語に詳しい方、よろしくお願いします。

// エラー内容 daemon.c:89:2: error: 'va_start' used in function with fixed args va_start(args, va_alist); ^ /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/12.0.5/include/stdarg.h:17:29: note: expanded from macro 'va_start' #define va_start(ap, param) __builtin_va_start(ap, param) ^ 1 error generated.
// daemon.c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> #include <syslog.h> //#include <varargs.h> #include <stdarg.h> #include <unistd.h> #include <signal.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include "daemon.h" #define MAXFD 64 static int IsDaemon=0; void InitDaemon(char *ident,int chdir_root,int all_fd_close) { int i,fd; pid_t pid; if((pid=fork())!=0){ exit(0); } setsid(); signal(SIGHUP,SIG_IGN); if((pid=fork())!=0){ exit(0); } IsDaemon=1; if(chdir_root){ chdir("/"); } if(all_fd_close){ for(i=0;i<MAXFD;i++){ close(i); } if((fd=open("/dev/null",O_RDWR,0))!=-1) { (void)dup2(fd,0); (void)dup2(fd,1); (void)dup2(fd,2); if(fd>2){ (void)close(fd); } } } openlog(ident,LOG_PID,LOG_NOTICE); } char *str_cut(char *str,int len) { static char *buf=NULL; static int buf_len=0; if(buf_len<=len){ if(buf!=NULL){ free(buf); } buf_len=len+1; buf=(char *)calloc(buf_len,sizeof(char)); } strncpy(buf,str,len); buf[len]='\0'; return(buf); } void lprintf(va_alist) //va_dcl { va_list args; char *fmt; char buf[513]; va_start(args, va_alist); fmt=va_arg(args,char *); vsnprintf(buf,sizeof(buf),fmt,args); buf[512]='\0'; if(IsDaemon){ } else{ fflush(stdout); fputs(str_cut(buf,512),stderr); fflush(stderr); } } void lperror(char *str) { char buf[513]; snprintf(buf,sizeof(buf),"%s : %s\n",str,strerror(errno)); buf[512]='\0'; if(IsDaemon){ } else{ fflush(stdout); fputs(str_cut(buf,512),stderr); fflush(stderr); } } #ifdef TEST int main() { char buf[2048]; int i; FILE *fp; InitDaemon("daemon:test",1,1); fprintf(stderr,"stderr\n"); lprintf("start\n"); lprintf("cwd=%s\n",getcwd(buf,sizeof(buf))); for(i=0;i<2047;i++){ buf[i]=i%10+'0'; } buf[2047]='\0'; lprintf(buf); if((fp=fopen("/dev/abcdefg","r"))==NULL){ lperror("fopen"); } lprintf("end\n"); } #endif

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

そうなるとvoid lprintf()の引数はどうすればいいでしょうか?

たとえばこんなかんじ:

C

1#include <stdio.h> 2#include <stdarg.h> 3 4void lprintf(const char* format,...) { 5 va_list args; 6 char buf[513]; 7 8 va_start(args, format); 9 int size = vsnprintf(buf, sizeof(buf), format, args); 10 buf[size]='\0'; 11 12 fputs(buf, stderr); 13} 14 15int main() { 16 lprintf("[%d : %c]\n", 123, 'A'); 17 return 0; 18}

投稿2021/07/13 12:21

episteme

総合スコア16614

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nyamagoyaki

2021/07/13 12:29

void lprintf(const char *fmt, ...) { va_list args; char buf[513]; va_start(args, fmt); fmt=va_arg(args,char *); vsnprintf(buf,sizeof(buf),fmt,args); buf[512]='\0'; if(IsDaemon){ } else{ fflush(stdout); fputs(str_cut(buf,512),stderr); fflush(stderr); } va_end(args); } としてみたのですが、今度は daemon.c:103:6: error: conflicting types for 'lprintf' void lprintf(char *fmt, ...) などと出てしまいます。どこが間違えているのでしょうか??
episteme

2021/07/13 12:33

このlprintfはヘッダ内(daemon.h?)で宣言されていますか? 宣言と定義は一致していますか?
nyamagoyaki

2021/07/13 12:38

daemon.hでは void lprintf(const char *fmt); と定義いたしましたが、 ./daemon.h:6:6: note: previous declaration is here void lprintf(const char *fmt); と出てしまいます。
episteme

2021/07/13 12:39

一致してないじゃん。
nyamagoyaki

2021/07/13 12:41

すみません。時間を置いたらできました。ありがとうございました!!
episteme

2021/07/13 12:45

時間を置いたら? どゆこと? カップヌードルじゃあるまいし。
guest

0

va_startを使う場合、それを呼ぶ関数に1つは固定の引数が必要です。それをva_startに渡して、可変長引数へのポインタを得ます(man)。

va_alistva_dclと組み合わせる、引数の型宣言のない関数の記法にしか使えず、va_startと併用するものではありません。

投稿2021/07/13 02:06

maisumakun

総合スコア145184

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nyamagoyaki

2021/07/13 05:05

本では上記のコードのように、va_startとva_alistを併用しているのですが、どう書き直せばよろしいでしょうか?
maisumakun

2021/07/13 05:12

本の正誤表は出ていませんか?
maisumakun

2021/07/13 05:13

あるいは、本の可変長引数の書き方は無視して、自分で...とva_startを使った関数を書いてみる、というのも一案です。
nyamagoyaki

2021/07/13 11:42

出ていないです... 書き直すとなると、va_alistやva_dclはなくなると思いますが、そうなるとvoid lprintf()の引数は どうすればいいでしょうか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問