0

Code:

char *color_name[] = {
    "red",
    "blue",
    "green"
};

#define color_num (sizeof(color_name)/sizeof(char*))

int main(){
    printf("size %d \n",color_num);
    return 0;
}

It works fine with GCC 4.8.2 on Centos 7.

But I got error running above program on mac which says:

note:expanded from macro 'color_num'

Compiler on my Mac:

……include/c++/4.2.1
Apple LLVM version 6.1.0 (clang-602.0.49) (based on LLVM 3.6.0svn)
Target: x86_64-apple-darwin14.3.0
Thread model: posix

I've been told that GCC has been linked to Clang on Mac when it is used to compile program, am I right?

Qestion:

So why does Clang report that error? Is that concerning pre-processing?

And if I do this, it works fine:

int a = color_num;
printf("%d\n",a);

or:

printf("%d\n",sizeof(color_num)/sizeof(char*));

UPDATA=============

Crayon_277@Macintosh 20150525$ gcc -g -o ex11 ex1.c
ex1.c:16:21: warning: format specifies type 'int' but the argument has type 'unsigned long' [-Wformat]
        printf("size %d\n",color_num);
                     ~~    ^~~~~~~~~
                     %lu
ex1.c:14:19: note: expanded from macro 'color_num'
#define color_num (sizeof(color)/sizeof(char*))
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 warning generated.

It seems no error but just that format warning.

I think it may concerning the extension I use for vim scrooloose/syntastic

I got error from that:

enter image description here

MMMMMCCLXXVII
  • 571
  • 1
  • 8
  • 23

2 Answers2

3

It is probably complaining that the expression expanded from color_num is an unsigned (perhaps unsigned long) while the format in the printf is a signed integer.

sizeof gives size_t, which is always an unsigned type, as noted in is size_t always unsigned?, but the number of bits depends on the implementation. Compiler warnings may — and often do — refer to the mismatch in terms of the equivalent type rather than size_t as such. The C standard after all, does not specify the nature of diagnostic messages.

When you changed that to an assignment, it is less strict, since that is a different check.

The "note" lines are something that the compiler adds to a warning/error message to help you understand where the problem came from.

(As the comment notes, you should quote the entire warning message, to make the question understandable).

Community
  • 1
  • 1
Thomas Dickey
  • 51,086
  • 7
  • 70
  • 105
  • sizeof return size_t; leave it to the toolchain what that actually maps to. – too honest for this site May 26 '15 at 01:26
  • @Olaf it does not return anything, it's an operator and it's evaluated at compile time. – Iharob Al Asimi May 26 '15 at 01:28
  • Thomas: Just reference the standard: n1570, 6.5.3.4/5 . And for an assignment - as for any other expression - default coercion rules are applied. However, gcc at least can (and should) are able to warn about some of those, too (-Wconversion e.g.). – too honest for this site May 26 '15 at 01:47
  • @iharob: how about a VLA? Anyway, every operator is actually a function, which takes argument(s) and returns a result. sizeof is not different in that from the unary '-' for instance. Note that the time of evaluation does not change that. The standard very well allows the compiler to evaluate a function at compile-time if it can prove it constant/pure. And it actually does: just think of expressions. Note that the stndard explicitly mentions it "yields" (6.5.3.4/2, also for VLAs). For C I take this as the same; but I will not discuss about the difference between "yield" and "return" here – too honest for this site May 26 '15 at 01:51
1

The sizeof gives the value with size_t type, the right format specifier for size_t is "%zu".

Iharob Al Asimi
  • 52,653
  • 6
  • 59
  • 97