Compile error

D

dspfun

Hi,

I get a compile/preprocessor error when trying to call/use the
following line:
openlog (__FUNCTION__, 0x02 | 0x01 | 0x08, (1<<3));


The openlog function is declared as:

extern void openlog (__const char *__ident, int __option, int
__facility);

The compiler error is:

------------------------------------------
powerpc-linux-gnu-gcc -c
....snip...
-Wno-write-strings foo.c -o foo.o
foo.c:62: error: expected declaration specifiers or '...' before
'__FUNCTION__'
....snip...
gmake[1]: *** [foo.o] Error 1
Command exited with non-zero status 2
------------------------------------------

Does anyone have any idea what the problem is and how to resolve it?

Brs,
Markus
 
D

dspfun

I tried with __func__ as well instead of __FUNCTION__ but the same
error.

Any ideas?

Brs,
Markus

Hi!

The problem is most likely related to that it's not possible to call
functions at file scope - they need to be inside another function.

The call to openlog() was actually embedded in a MACRO, which in turn
was embedded into another MACRO, so it was a bit confusing. The code I
put above had I extracted from after the preprocessor had been run..

Thanks!

Markus
 
B

BartC

dspfun said:
Hi,

I get a compile/preprocessor error when trying to call/use the
following line:
openlog (__FUNCTION__, 0x02 | 0x01 | 0x08, (1<<3));


The openlog function is declared as:

extern void openlog (__const char *__ident, int __option, int
__facility);
Does anyone have any idea what the problem is and how to resolve it?

What happens when __FUNCTION__ is replaced with NULL or 0? What happens when
you change __const to const (or leave it out altogether)?
 
K

Keith Thompson

dspfun said:
I get a compile/preprocessor error when trying to call/use the
following line:
openlog (__FUNCTION__, 0x02 | 0x01 | 0x08, (1<<3));


The openlog function is declared as:

extern void openlog (__const char *__ident, int __option, int
__facility);

Is "__const" a macro for "const"? If so, why not just use "const"?
If it's to cater to compilers that don't support "const", I hardly think
that's necessary these days.

Why are the parameter names reserved identifiers? (The implementation
is free to define "__ident" as a macro, which would break the
declaration.)

[...]
 
I

Ian Collins

Is "__const" a macro for "const"? If so, why not just use "const"?
If it's to cater to compilers that don't support "const", I hardly think
that's necessary these days.

Why are the parameter names reserved identifiers? (The implementation
is free to define "__ident" as a macro, which would break the
declaration.)

It looks like a bastardised version of the standard Unix function
declaration:

void openlog(const char *ident, int logopt, int facility);
 
K

Kaz Kylheku

Is "__const" a macro for "const"? If so, why not just use "const"?

Yes and no. GCC has such a keyword.

In the GNU C Library /usr/include/sys/cdefs.h we have this:

#ifdef __GNUC__

/* GCC can always grok prototypes. For C++ programs we add throw()
to help it optimize the function calls. But this works only with
gcc 2.8.x and egcs. For gcc 3.2 and up we even mark C functions
as non-throwing using a function attribute since programs can use
the -fexceptions options for C code as well. */
# if !defined __cplusplus && __GNUC_PREREQ (3, 3)
# define __THROW __attribute__ ((__nothrow__))
# define __NTH(fct) __attribute__ ((__nothrow__)) fct
# else
# if defined __cplusplus && __GNUC_PREREQ (2,8)
# define __THROW throw ()
# define __NTH(fct) fct throw ()
# else
# define __THROW
# define __NTH(fct) fct
# endif
# endif

#else /* Not GCC. */

# define __inline /* No inline functions. */

# define __THROW
# define __NTH(fct) fct

# define __const const
# define __signed signed
# define __volatile volatile

#endif /* GCC. */
If it's to cater to compilers that don't support "const", I hardly think
that's necessary these days.

It avoids unnecessary namespace pollution, I suppose. A program can use
const as a macro and it won't interfere with the GNU C Library headers.

*shrug*

Good questions for the glibc mailing list.
 
J

Jorgen Grahn

Is "__const" a macro for "const"? If so, why not just use "const"?
If it's to cater to compilers that don't support "const", I hardly think
that's necessary these days.

Why are the parameter names reserved identifiers? (The implementation
is free to define "__ident" as a macro, which would break the
declaration.)

To be fair to Linux glibc (from where he must have copied the above),
the manual page uses the normal names.

/Jorgen
 
K

Keith Thompson

Jorgen Grahn said:
To be fair to Linux glibc (from where he must have copied the above),
the manual page uses the normal names.

So, dspfun, where did the identifiers __ident et al come from?
 
B

Ben Pfaff

Keith Thompson said:
So, dspfun, where did the identifiers __ident et al come from?

On a glibc system:

blp@blp:~$ grep -r __ident /usr/include
/usr/include/sys/syslog.h:extern void openlog (__const char *__ident, int __option, int __facility);
blp@blp:~$
 
K

Kaz Kylheku

So, dspfun, where did the identifiers __ident et al come from?

Wow, this insipid buffoon is still going on about this, when it's been clear to
everyone that this declaration is from a system header that is making use of a
namespace reserved for implementors.

If the implementation of a standard header has a declaration like

extern int fputc(int ch, FILE *stream); /* no underscores */

this creates a problem if a program does something like this:

#define ch blah()
#include <stdio.h> /* now we have int fputc(int blah(), FILE *stream). */

This #define is allowed, because ch is not a keyword, and it is not an
identifier that is reserved with respect to this header file. It is the
header that is wrong by using unreserved identifiers in a way that is visible
to the program.

One solution is to not use names:

extern int fputc(int, FILE *);

but maybe library implementors sometimes want names there, which can sometimes
be helpful. Also, this issue occurs with struct and union member names, where
you can't omit the name:

struct stat {
dev_t st_dev; /* standard member; user cannot #define st_dev */

/*...*/

void *__padding[2]; /* for some kernel issue or whatever ... */

/*...*/
};

The library writer doesn't have to worry that user programs will
#define __padding ... because that is equivalent to sticking a fork into a
toaster.
 
K

Keith Thompson

On a glibc system:

blp@blp:~$ grep -r __ident /usr/include
/usr/include/sys/syslog.h:extern void openlog (__const char *__ident, int __option, int __facility);
blp@blp:~$

Ok, that makes some sense, given that /usr/include/sys/syslog.h is
part of the implementation.

The name of a parameter in a function declaration (as opposed to a
definition) is ignored; there's no way in C for a caller to refer
to a parameter by name. The authors of syslog.h decided to use
reserved identifiers to avoid clashing with user-defined macros.
For example, if they had written:

extern void openlog (__const char *ident, int option, int facility);

and a user wrote:

#define ident 42
#include <sys/syslog.h>

then the declaration would be a syntax error.

The lesson here is that system header files are intended for the
compiler, not necessarily for human readers (unless you have a
specific need to dive into the gory details); they can have all sorts
of implementation-defined cruft that's of no interest to most users.
The way to get the declaration for openlog() is to read the man page,
which says:

#include <syslog.h>

void openlog(const char *ident, int option, int facility);

As for __const, that's a gcc-specific "alternate keyword".
It probably goes back to the pre-ANSI days when some compilers didn't
support the "const" keyword. It's equivalent (for gcc) to "const",
and there's no reason to use it or refer to it in your own code.
 
D

dspfun

Ok, that makes some sense, given that /usr/include/sys/syslog.h is
part of the implementation.

The name of a parameter in a function declaration (as opposed to a
definition) is ignored; there's no way in C for a caller to refer
to a parameter by name.  The authors of syslog.h decided to use
reserved identifiers to avoid clashing with user-defined macros.
For example, if they had written:

    extern void openlog (__const char *ident, int option, int facility);

and a user wrote:

    #define ident 42
    #include <sys/syslog.h>

then the declaration would be a syntax error.

The lesson here is that system header files are intended for the
compiler, not necessarily for human readers (unless you have a
specific need to dive into the gory details); they can have all sorts
of implementation-defined cruft that's of no interest to most users.
The way to get the declaration for openlog() is to read the man page,
which says:

    #include <syslog.h>

    void openlog(const char *ident, int option, int facility);

As for __const, that's a gcc-specific "alternate keyword".
It probably goes back to the pre-ANSI days when some compilers didn't
support the "const" keyword.  It's equivalent (for gcc) to "const",
and there's no reason to use it or refer to it in your own code.

--
Keith Thompson (The_Other_Keith) (e-mail address removed)  <http://www.ghoti.net/~kst>
    Will write code for food.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

Hi,

Thanks all for your help!

Here is more info regarding where the __const etc comes from in my
code:

My .c-file uses the macro TRACE_OBJ(GROUP,TRACE_OBJ,MSG) and this
macro is declared in the file

/usr/include/xxx_trace_obj.h

as

#define TRACE_OBJ(GROUP,TRACE_OBJ,MSG) LOG(LOG_INFO, STR("TRACE_OBJ:
%s", #TRACE_OBJ))

LOG_INFO is defined as
#define LOG_INFO 6

and STR is defined as
-------------------------
static char buf_s[1024];

static char* STR(const char *fmt, ...)
{
va_list args;

__builtin_va_start(args,fmt);
(void)vsprintf(buf_s, fmt, args);
__builtin_va_end(args);
return (char*)buf_s;
}
-------------------------

The LOG macro is declared in the file

/usr/include/slog.h

as

#define LOG(level, msg) do {\
openlog (__FUNCTION__, LOG_CONS | LOG_PID | LOG_NDELAY, LOG_USER);\
syslog (level, "%s", msg);\
closelog ();\
} while(0)


slog.h above includes the file
/usr/include/syslog.h"

which only contains

#include <sys/syslog.h>

and sys/syslog.h contains the declaration of openlog

/* Open connection to system logger.
This function is a possible cancellation point and therefore not
marked with __THROW. */
extern void openlog (__const char *__ident, int __option, int
__facility);

Brs,
Markus
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

glibc ARM cross compile error 2
Compile Error 3
Compile error. 3
Compile error 3
re-compile error 13
Compilation error on AIX 1
Functor Compilation Error 2
ERROR: storage size of 'tzp' isn't known 1

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,011
Latest member
AjaUqq1950

Latest Threads

Top