My environment is Windows XP SP3 + 'Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 14.00.50727.762 for 80x86'. The process is as follows:
F:\workshop\vc8proj\console> type t.c
int main(void) {
// Do some thing.
{
int i;
{
i = 3;
goto abc111;
}
abc111:
}
return 0;
}
F:\workshop\vc8proj\console> cl /MD t.c Microsoft (R) 32-bit C/C++
Optimizing Compiler Version 14.00.50727.762 for 80x86
Copyright (C) Microsoft Corporation. All rights reserved.
t.c t.c(10) : error C2143: syntax error : missing ';' before '}'
F:\workshop\vc8proj\console>vim t.c
F:\workshop\vc8proj\console>type t.c
int main(void) {
// Do some thing.
{
int i;
{
i = 3;
goto abc111;
}
abc111: 5201314;
}
return 0;
}
F:\workshop\vc8proj\console> cl /MD t.c Microsoft (R) 32-bit C/C++
Optimizing Compiler Version 14.00.50727.762 for 80x86
Copyright (C) Microsoft Corporation. All rights reserved.
t.c Microsoft (R) Incremental Linker Version 8.00.50727.762 Copyright
(C) Microsoft Corporation. All rights reserved.
/out:t.exe t.obj
F:\workshop\vc8proj\console>
Under the Linux operating system the same situation, too???
It's a language feature. A label can only be part of a labeled statement, and the statement needs a terminating ;. Just putting a semicolon behind the label suffices.
int main(void) {
// Do some thing.
{
int i;
{
i = 3;
goto abc111;
}
abc111: ;
}
return 0;
}
works too.
Well, it is a language feature. It is compulsory that there should be a statement to which we mentioned the label.
If there isn't any statement after the label then just put a ';' to terminate the statement or you can write a return statement after the label only.
Related
I am learning c++ and the excersise involves opening a .txt file and reading from it.
The project structure is as following:
int main()
{
static const char* full_name = "C:\Users\Lukas\Desktop\Programming\file_system_test\file_system_test\items.txt";
FILE* my_file = fopen(full_name , "r");
if (my_file == NULL) {
perror("error opening file");
}
}
I am trying to fopen items.txt but with no luck yet..
I am not exactly sure what is the problem since I provide the full path..
METHODS TRIED SO FAR:
Using double backslash in full path
static const char* full_name = "C:\\Users\\Lukas\Desktop\\Programming\\file_system_test\\file_system_test\\items.txt";
Error still persists with:
error opening file: No such file or directory
SOLVED
The only thing that seems to fix this code is to use raw string literal as following:
static const char* full_name3 = R"(C:/Users/Lukas/Desktop/Programming/file_system_test/file_system_test/items.txt)";
FILE* my_file3 = fopen(full_name3, "r");
if (my_file3 == NULL) {
perror("error opening file");
}
Does not return any errors anymore.
Note escape sequences of string literals, so your path:
static const char* full_name = "C:\Users\Lukas\Desktop\Programming\file_system_test\file_system_test\items.txt";
contains \f escape sequence which is interpreted as form feed - new page byte 0x0c in ASCII encoding. This character can't be part of of a path so Invalid argument error is reported.
Also compilers complain that other escape sequences are unknown.
There are three ways to fix it.
As Luka Rahne suggested by using back slash escape sequence \\
Or by using forward slashes (since C suppose to be portable, standard library is able to convert Unix path separator to platform specific path separators).
static const char* full_name = "C:/Users/Lukas/Desktop/Programming/file_system_test/file_system_test/items.txt";
If you are using C++11 or newer (your code is C not C++, but tag says C++), you can leverage raw string literal:
static const char* full_name = R"(C:\Users\Lukas\Desktop\Programming\file_system_test\file_system_test\items.txt)";
Here I did some live testing with msvc (file named: open.c):
#include <stdlib.h>
#include <stdio.h>
int main(int argc, const char argv[])
{
#if VERSION == 0
// here '\f' is used to reproduce error "invalid argument":
static const char name[] = "C:\fUsers\\User\\Downloads\\open.c";
#elif VERSION == 1
static const char name[] = "C:\\Users\\User\\Downloads\\open.c";
#elif VERSION == 2
static const char name[] = "C:/Users/User/Downloads/open.c";
#elif VERSION == 3
static const char name[] = R"(C:\Users\User\Downloads\open.c)";
#endif
FILE* f = fopen(name, "r");
if (!f) {
perror("fopen");
return 1;
}
char buf[256] = "";
fgets(buf, sizeof(buf), f);
printf("%s\n", buf);
fclose(f);
return 0;
}
Here is result of compiling and running from cmd.exe:
C:\Users\User\Downloads>cl open.c /D VERSION=0 && open.exe
Microsoft (R) C/C++ Optimizing Compiler Version 19.28.29336 for x86
Copyright (C) Microsoft Corporation. All rights reserved.
open.c
Microsoft (R) Incremental Linker Version 14.28.29336.0
Copyright (C) Microsoft Corporation. All rights reserved.
/out:open.exe
open.obj
fopen: Invalid argument
C:\Users\User\Downloads>cl open.c /D VERSION=1 && open.exe
Microsoft (R) C/C++ Optimizing Compiler Version 19.28.29336 for x86
Copyright (C) Microsoft Corporation. All rights reserved.
open.c
Microsoft (R) Incremental Linker Version 14.28.29336.0
Copyright (C) Microsoft Corporation. All rights reserved.
/out:open.exe
open.obj
#include <stdlib.h>
C:\Users\User\Downloads>cl open.c /D VERSION=2 && open.exe
Microsoft (R) C/C++ Optimizing Compiler Version 19.28.29336 for x86
Copyright (C) Microsoft Corporation. All rights reserved.
open.c
Microsoft (R) Incremental Linker Version 14.28.29336.0
Copyright (C) Microsoft Corporation. All rights reserved.
/out:open.exe
open.obj
#include <stdlib.h>
C:\Users\User\Downloads>cl open.c /D VERSION=3 && open.exe
Microsoft (R) C/C++ Optimizing Compiler Version 19.28.29336 for x86
Copyright (C) Microsoft Corporation. All rights reserved.
open.c
open.c(11): warning C4129: 'm': unrecognized character escape sequence
open.c(11): warning C4129: 'D': unrecognized character escape sequence
open.c(11): warning C4129: 'o': unrecognized character escape sequence
open.c(11): error C2065: 'R': undeclared identifier
open.c(11): error C2143: syntax error: missing ';' before 'string'
open.c(11): error C2099: initializer is not a constant
So everything works as I described and last version 3 fails since I compile code as C.
I believe your issue is that \ in filename is not properly escaped.
Your filename string should have double backslash characters.
static const char* full_name = "C:\\Users\\Lukas\\Desktop\\Programming\\file_system_test\\file_system_test\\items.txt";
You can test this, by sending this string trough std::cout for debug.
When I try to print the copyright symbol © with printf or write, it works just fine:
#include <stdio.h>
int main(void)
{
printf("©\n");
}
#include <unistd.h>
int main(void)
{
write(1, "©\n", 3);
}
Output:
©
But when I try to print it with wprintf, I get (C):
#include <stdio.h>
#include <wchar.h>
int main(void)
{
wprintf(L"©\n");
}
Output:
(C)
It's fixed when I add a call to setlocale, though:
#include <stdio.h>
#include <wchar.h>
#include <locale.h>
int main(void)
{
setlocale(LC_ALL, "");
wprintf(L"©\n");
}
Output:
©
Why is the original behavior present and why is it fixed when I call setlocale? Additionally, where does this conversion take place? And how can I make the behavior after setlocale the default?
compilation command:
gcc test.c
locale:
LANG=en_US.UTF-8
LANGUAGE=
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=
echo $LC_CTYPE:
uname -a:
Linux penguin 4.19.79-07511-ge32b3719f26b #1 SMP PREEMPT Mon Nov 18 17:41:41 PST 2019 x86_64 GNU/Linux
file test.c (same on all of the examples):
test.c: C source, UTF-8 Unicode text
gcc --version:
gcc (Debian 6.3.0-18+deb9u1) 6.3.0 20170516
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
/lib/x86_64-linux-gnu/libc-2.24.so (glibc version):
GNU C Library (Debian GLIBC 2.24-11+deb9u4) stable release version 2.24, by Roland McGrath et al.
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
Compiled by GNU CC version 6.3.0 20170516.
Available extensions:
crypt add-on version 2.1 by Michael Glad and others
GNU Libidn by Simon Josefsson
Native POSIX Threads Library by Ulrich Drepper et al
BIND-8.2.3-T5B
libc ABIs: UNIQUE IFUNC
For bug reporting instructions, please see:
<http://www.debian.org/Bugs/>.
cat /etc/debian_version:
9.12
The locale of the calling processes is not automatically inherited by the new process.
When the program first starts up, it is in the C locale. The man page for setlocale(3) says the following:
On startup of the main program, the portable "C" locale is selected
as default. A program may be made portable to all locales by calling:
setlocale(LC_ALL, "");
...
The locale "C" or "POSIX" is a portable locale; its LC_CTYPE part corresponds to the 7-bit ASCII character set.
So any multibyte / non-ASCII character is converted into one or more ASCII characters as the output shows.
The locale can be set as follows:
setlocale(LC_ALL, "");
The LC_ALL flag specifies changing all locale-related variables. An empty string for the locale means to set the locale according to the relevant environment variables. Once this is done, you should see the characters for your shell's locale.
#include <stdio.h>
#include <wchar.h>
#include <locale.h>
int main()
{
char *before = setlocale(LC_ALL, NULL);
setlocale(LC_ALL, "");
char *after = setlocale(LC_ALL, NULL);
wprintf(L"before locale: %s\n", before);
wprintf(L"after locale: %s\n", after);
wprintf(L"©\n");
wprintf(L"\u00A9\n");
return 0;
}
Output:
before locale: C
after locale: en_US.utf8
©
©
I am reading an introduction to gcc in which it says:
‘-Wcast-qual’ this option warns about pointers that are cast to remove
a type qualifier, such as const. For example, the following function
discards the const qualifier from its input argument, allowing it to
be overwritten:
void
f (const char * str)
{
char * s = (char *)str;
s[0] = ’\0’; }
The modification of the original contents of str is a violation of its
const property. This option will warn about the improper cast of the
variable str which allows the string to be modified.
I tried to repeat this, expecting a warning, but there's no warning when it is compiled. My code is as follows:
#include <stdio.h>
void f(const char * str);
int main() {
char Str = 'a';
char * myStr;
myStr = & Str;
printf ("result: %c \n", * myStr);
f(myStr);
printf ("result: %c \n", * myStr);
return 0;
}
void
f (const char * str)
{
char * s = (char *)str;
s[0] = '\0';
}
the command is : gcc -Wcast-qual castqual.c
Can anyone explain this inconsistency?
Per the comments, it turns out that the OP is using a mac, where gcc as a command is a wrapper around clang - the llvm based compiler.
The version of clang that's being used accepts the option but does nothing with it. Support for the warning is being added and should appear in the XCode 7/clang 7 timeframe; however the question was about gcc and not about clang.
In this case, you need to install a proper copy of gcc using, either manually or using a package manager such as homebrew or macports. Once you've installed gcc, it becomes available as, for example, gcc-4.8, gcc-5, etc (depends on the package manager). When you want to compile code with actual gcc, you use: gcc-4.8 -Wcast-qual testcode.c. If you're using autoconf tools you can use export CC=gcc-4.8; export CXX=g++-4.8, etc. and then that compiler will be picked up by the package.
Verifying that you're calling gcc, rather than clang requires checking the output from gcc --version. On a clang wrapper you see things like:
$ gcc --version
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 6.1.0 (clang-602.0.53) (based on LLVM 3.6.0svn)
Target: x86_64-apple-darwin14.4.0
Thread model: posix
whereas on an actual gcc instance you see:
$ gcc-5 --version
gcc-5 (Homebrew gcc 5.1.0) 5.1.0
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
imho aside: you can make a symlink to the specific gcc-4.8 called gcc, and get it to invoke directly like that but it can break other things.
I am using
p12user#ubuntu:~$ uname -a
Linux ubuntu 2.6.32-40-generic #87-Ubuntu SMP Tue Mar 6 00:56:56 UTC 2012 x86_64 GNU/Linux
p12user#ubuntu:~$ gdb -v
GNU gdb (GDB) 7.1-ubuntu
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
p12user#ubuntu:~/programming$ gcc --version
gcc (Ubuntu 4.4.3-4ubuntu5.1) 4.4.3
Copyright (C) 2009 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
On debugging this program in gdb, which is compiled as gcc -g program.c:
#include <stdio.h>
int main()
{
int condition1 = 1;
if(condition1)
{
if(!condition1)
{
printf("The control shouldn't come here.\n");
}
}
else
{
printf("in else\n");
}
return 0;
}
the behaviour is:
Breakpoint 1, main () at program.c:4
4 int condition1 = 1;
(gdb) n
5 if(condition1)
(gdb) n
7 if(!condition1)
(gdb) n
9 printf("The control shouldn't come here.\n");
(gdb) n
16 return 0;
(gdb) n
17 }
(gdb)
The behaviour at LINE 9 is unexpected in gdb. However, the print statement is only shown in gdb but not executed. And if I put a matching ELSE (with some print statement) with inner-IF then this doesn't happen, also if matching ELSE for outer-IF is removed then this doesn't happen. Am I missing something trivial here?
Make sure you're building your program without any kinds of optimization, as the program you've shown seems to be trivially optimizable which can lead to source code statements not making into the executable.
In GCC you'd use:
gcc -O0 ...
or
g++ -O0 ...
for this.
in
2.6.18-164.el5 #1 SMP Tue Aug 18 15:51:48 EDT 2009 x86_64 x86_64 x86_64 GNU/Linux
gcc version 4.1.2 20080704 (Red Hat 4.1.2-46)
GNU gdb Fedora (6.8-37.el5)
it is ok!
I am currently trying to learn C by using the K&R, but I am completely stumped by example 1.5.2. For some reason, after I press Ctrl-Z, instead of printing nc, it prints nc multiplied by 2. I don't know what could be causing this problem (I copied the code exactly how it is in the book). The compiler I am using is Visual Studio 2010. Here is the code:
#include <stdio.h>
main()
{
long nc;
nc = 0;
while (getchar() != EOF)
++nc;
printf("%1d\n", nc);
}
Because enter is a keystroke.
If your input is:
1<enter>
1<enter>
1<enter>
^z
it would output:
6
Not sure why you get the behaviour you describe but that should be %ld not %1d
Could not reproduce your error. I added some debugging statements,
#include <stdio.h>
main() {
int nc = 0, ch;
while ((ch = getchar()) != EOF) {
printf("%d\n", ch);
++nc;
}
printf("nc - %1d\n", nc);
}
And then tried it with gcc on Windows:
E:\temp>gcc eof.c
E:\temp>a
^Z
nc - 0
E:\temp>a
foo bar
102
111
111
32
98
97
114
10
^Z
nc - 8
And then with Visual Studio 2008:
E:\temp>cl eof.c
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 15.00.30729.01 for 80x86
Copyright (C) Microsoft Corporation. All rights reserved.
eof.c
Microsoft (R) Incremental Linker Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.
/out:eof.exe
eof.obj
E:\temp>eof
^Z
nc - 0
E:\temp>eof
foo bar
102
111
111
32
98
97
114
10
^Z
nc - 8