<div dir="ltr">&#39;\0&#39; is a single character, not a string. Note the use of signal quote marks, THIS IS IMPORTANT. It is an 8bit value equivalent to the byte 0x00, or an integer 0x00000000. You could replace &#39;\0&#39; with 0x00 everywhere in your code and they would be exactly the same.<div><br></div><div>&quot;&quot; is a string containing one byte, &#39;\0&#39;. It&#39;s equivalent to a byte array like { 0x00 }. This array is allocate somewhere in memory, not a literal value in your program like the previous example.</div><div><br></div><div>When you say &quot;const char *&quot; that&#39;s a C-ism for saying you want an array of bytes. An array in C is passed by the address of the first element. This is why clang (correctly) throws a warning.</div><div><br></div><div>In your first case, clang sees you have a literal 0x00 when a pointer value is expected. But it says &quot;Hey, I can take that literal 0x00 and cast it to a pointer value!&quot; It throws a warning because this isn&#39;t usually a good thing to do, but in this case it is equivalent to NULL so it kind of works. For example, if you had used a literal &#39;A&#39;, then clang would pass in the pointer value 0x41, which would try to access whatever memory is at address 0x00000041, which is almost certainly crash.</div><div><br></div><div>In your second case, clang sees you have an array of one byte (it doesn&#39;t care about the arrays contents), and passes the address of the first element of the array. This array is allocated in the global data section of your program. Let&#39;s pretend the address of that first element is 0xDEADBEEF.</div><div><br></div><div>Can you see the difference? In the first case clang has to cast character (or integer) to a char*, which is usually dangerous. In the second case it is given the proper type (a memory address) that the function argument says it wants.</div><div><br></div><div>It&#39;s would really worry me that the upstream developers of this package don&#39;t understand the difference.</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Jun 21, 2016 at 1:21 AM, Mojca Miklavec <span dir="ltr">&lt;<a href="mailto:mojca@macports.org" target="_blank">mojca@macports.org</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi,<br>
<br>
When I tried porting some software (originally written for Windows and<br>
now asking for C++14) to MacPorts I was stuck with an external piece<br>
of a code written in C, compiled with C++ (I don&#39;t fully understand<br>
why it is compiled with C++, but I cannot change that).<br>
<br>
This is a minimal example that fails:<br>
<br>
    void test(const char *a) {}<br>
    int main()<br>
    {<br>
        test(&#39;\0&#39;); // pass an empty string<br>
        return 0;<br>
    }<br>
<br>
<br>
A relatively recent clang++ compiler just throws a warning (using libstdc++):<br>
<br>
&gt; clang++-mp-3.7 test-dev.c<br>
clang: warning: treating &#39;c&#39; input as &#39;c++&#39; when in C++ mode, this<br>
behavior is deprecated<br>
test-dev.c:5:10: warning: expression which evaluates to zero treated<br>
as a null pointer constant of type &#39;const char *&#39;<br>
[-Wnon-literal-null-conversion]<br>
    test(&#39;\0&#39;);<br>
         ^~~~<br>
1 warning generated.<br>
<br>
<br>
But the same compiler in C++11 or C++14 mode throws an error:<br>
<br>
&gt; clang++-mp-3.7 -stdlib=libc++ -std=c++14 test-dev.c<br>
clang: warning: treating &#39;c&#39; input as &#39;c++&#39; when in C++ mode, this<br>
behavior is deprecated<br>
test-dev.c:5:5: error: no matching function for call to &#39;test&#39;<br>
    test(&#39;\0&#39;);<br>
    ^~~~<br>
test-dev.c:1:6: note: candidate function not viable: no known<br>
conversion from &#39;char&#39; to &#39;const char *&#39; for 1st argument<br>
void test(const char *a) {}<br>
     ^<br>
1 error generated.<br>
<br>
<br>
GCC doesn&#39;t seem to care though:<br>
<br>
&gt; g++-mp-4.9 -std=c++14 test-dev.c<br>
&gt; # no warnings or errors<br>
<br>
<br>
I didn&#39;t test on Windows. I installed clang 3.5 on Linux (the latest<br>
version shipped by Debian-based Mint) and the results were the same as<br>
on Mac:<br>
<br>
&gt; clang++-3.5 -std=c++11 tes-dev.c<br>
clang: warning: treating &#39;c&#39; input as &#39;c++&#39; when in C++ mode, this<br>
behavior is deprecated<br>
test-dev.c:4:5: error: no matching function for call to &#39;test&#39;<br>
    test(&#39;\0&#39;);<br>
    ^~~~<br>
test-dev.c:1:6: note: candidate function not viable: no known<br>
conversion from &#39;char&#39; to &#39;const char *&#39; for 1st argument<br>
void test(const char *a) {}<br>
     ^<br>
1 error generated.<br>
<br>
&gt; clang++-3.5 test-dev.c<br>
clang: warning: treating &#39;c&#39; input as &#39;c++&#39; when in C++ mode, this<br>
behavior is deprecated<br>
test-dev.c:4:10: warning: expression which evaluates to zero treated<br>
as a null pointer constant of type &#39;const char *&#39;<br>
[-Wnon-literal-null-conversion]<br>
    test(&#39;\0&#39;);<br>
         ^~~~<br>
1 warning generated.<br>
<br>
I came up with a workaround, defining<br>
<br>
   const char *empty = &quot;&quot;;<br>
   test(empty);<br>
<br>
<br>
The upstream developers replied:<br>
<br>
first:<br>
&gt; If I&#39;m understanding correctly, it also seems like a bug in the C++<br>
&gt; compiler to think that a character constant is not const,<br>
<br>
second:<br>
&gt; If I understand the patch well, the C code supplies a character \0<br>
&gt; when an empty string is expected. In K&amp;R C it is the same but strictly<br>
&gt; checking in C++ they are different things.<br>
<br>
<br>
So I was wondering which compiler was right: g++ or clang++?<br>
<br>
Mojca<br>
_______________________________________________<br>
macports-dev mailing list<br>
<a href="mailto:macports-dev@lists.macosforge.org">macports-dev@lists.macosforge.org</a><br>
<a href="https://lists.macosforge.org/mailman/listinfo/macports-dev" rel="noreferrer" target="_blank">https://lists.macosforge.org/mailman/listinfo/macports-dev</a><br>
</blockquote></div><br></div>