I am writing a simple program that using struct tcphdr in netinet/tcp.h as follows:
#define _BSD_SOURCE
#include <netinet/tcp.h>
#include <stdio.h>
int main()
{
struct tcphdr t;
t.th_sport = 0;
printf("\n%d", t.th_sport);
return 1;
}
Because I want this program can work on both FreeBSD and Centos, so I am using the FreeBSD-based property. I also defined _BSD_SOURCE in the beginning of file. But it could not be compiled using std=c++11 when I save this source code into *.cpp file. There is no member named th_sport. However, it is compiled perfectly by std=c99 with *.c file.
What's problem here? Anyone helps me to explain this? Thanks so much.
Related
I am new to C++ Programming. I'm getting Segmentation Fault error while compiling my code in online compilers but when I try compile it using Visual Studio Code and g++ in offline(means in my local machine) works fine.
The Code I have tried is
`
#include <iostream>
int main() {
int *ptr;
*ptr = 10;
cout<<*ptr; //Prints 10
cout<<ptr; //Prints Some garbage address
}
But the above program not working in online compilers(used onlinegdb).
My machine configuration
g++ 11
Visual Studio Code 2016
This line *ptr = 10; is fundamentally wrong, as you cannot assign value by dereferencing a pointer.
The correct method of doing so, would be:
#include <iostream>
using namespace std;
int a=10;
int *ptr;
ptr=&a;
cout<<ptr<<endl;
cout<<*ptr<<endl;
I have a strange segmentation fault that doesn't exist when everything is in 1 .c file, but does exist when I put part of the code in a dynamically linked library and link it to a test file. The complete code for the working 1 .c file code is at the bottom, the complete code for the error system with 2 .c and 1 .h file come first.
Here is the error system:
example.h:
#include <stdio.h>
#include <stdlib.h>
typedef struct MYARRAY {
int len;
void* items[];
} MYARRAY;
MYARRAY *collection;
void
mypush(void* p);
example.c:
#include "example.h"
void
mypush(void* p) {
printf("Here %lu\n", sizeof collection);
puts("FOO");
int len = collection->len++;
puts("BAR");
collection->items[len] = p;
}
example2.c:
This is essentially a test file:
#include "example.h"
void
test_print() {
puts("Here1");
mypush("foo");
puts("Here2");
}
int
main() {
collection = malloc(sizeof *collection + (sizeof collection->items[0] * 1000));
collection->len = 0;
puts("Start");
test_print();
puts("Done");
return 0;
}
Makefile:
I link example to example2 here, and run:
example:
#clang -I . -dynamiclib \
-undefined dynamic_lookup \
-o example.dylib example.c
#clang example2.c example.dylib -o example2.o
#./example2.o
.PHONY: example
The output is:
$ make example
Start
Here1
Here 8
FOO
make: *** [example] Segmentation fault: 11
But it should show the full output of:
$ make example
Start
Here1
Here 8
FOO
BAR
Here2
Done
The weird thing is everything works if it is this system:
example.c:
#include <stdio.h>
#include <stdlib.h>
typedef struct MYARRAY {
int len;
void* items[];
} MYARRAY;
MYARRAY *collection;
void
mypush(void* p) {
printf("Here %lu\n", sizeof collection);
puts("FOO");
int len = collection->len++;
puts("BAR");
collection->items[len] = p;
}
void
test_print() {
puts("Here1");
mypush("foo");
puts("Here");
}
int
main() {
collection = malloc(sizeof *collection + (sizeof collection->items[0] * 1000));
collection->len = 0;
puts("ASF");
test_print();
return 0;
}
Makefile:
example:
#clang -o example example.c
#./example
.PHONY: example
Wondering why it's creating a segmentation fault when it is linked like this, and what I am doing wrong.
I have checked otool and with DYLD_PRINT_LIBRARIES=YES and it shows it is importing the dynamically linked libraries, but for some reason it's segmentation faulting when linked but works fine when it isn't linked.
Your problem is this, in example.h:
MYARRAY *collection;
Since both main.c and example.c include this file, you end up defining collection twice, which results in undefined behavior. You need to make sure you define each object only once. The details are relatively unimportant since anything can happen with undefined behavior, but what's probably happening is that main.c is allocating memory for one object, but the one example.c is using is still NULL. As mentioned in the comments, since you define collection in main.c your linker is able to build the executable without needing to look for that symbol in the dynamic library, so you don't get a link time warning about it being defined there too, and obviously there'd be no cause for a warning at the time you compile the library.
It works for you when you put everything in one file because obviously then you're not defining anything twice, anymore. The error itself is nothing to do with the fact you're using a dynamic library, although that may have made it harder to detect.
It would be better to define this in example.c and provide a constructor function, there's no need for main() to be able to access it directly. But if you must do this, then define it in example.c and just declare an extern identifier in the header file to tell main.c that the object is defined somewhere else.
l learned "include" keyword are just copy & paste.
But including cpp file makes different compile result.
(gcc6~8 + boost1.69)
// main.cpp
#include <iostream>
// I'll move next code to why.cpp
#include <boost/archive/iterators/base64_from_binary.hpp>
#include <boost/archive/iterators/binary_from_base64.hpp>
#include <boost/archive/iterators/transform_width.hpp>
#include <boost/archive/iterators/insert_linebreaks.hpp>
#include <boost/archive/iterators/remove_whitespace.hpp>
void testFunc()
{
using namespace boost::archive::iterators;
typedef transform_width<binary_from_base64<remove_whitespace<std::string::const_iterator>>, 8, 6> ItBinaryT;
std::string input;
std::string output(ItBinaryT(input.begin()), ItBinaryT(input.end()));
}
// -----------------------------
int main()
{
return 0;
}
Above code compiled without warning.
But, I replace some code with include cpp..
// main.cpp
#include <iostream>
#include "why.cpp" // <----------
int main()
{
return 0;
}
// why.cpp - just copy&paste
#include <boost/archive/iterators/base64_from_binary.hpp>
#include <boost/archive/iterators/binary_from_base64.hpp>
#include <boost/archive/iterators/transform_width.hpp>
#include <boost/archive/iterators/insert_linebreaks.hpp>
#include <boost/archive/iterators/remove_whitespace.hpp>
void testFunc()
{
using namespace boost::archive::iterators;
typedef transform_width<binary_from_base64<remove_whitespace<std::string::const_iterator>>, 8, 6> ItBinaryT;
std::string input;
std::string output(ItBinaryT(input.begin()), ItBinaryT(input.end()));
}
It makes warning [-Wsubobject-linkage]
~~ has a field ~~ whose type uses the anonymous namespace
~~ has a base ~~ whose type uses the anonymous namespace
Please look at this link : https://wandbox.org/permlink/bw53IK2ZZP5UWMGk
What makes this difference?
Your compiler treats the main CPP file specially under the assumption that things defined in it are very unlikely to have more than one definition and so some tests for possible violation of the One Definition Rule are not done inside that file. Using #include takes you outside that file.
I would suggest just not using -Wsubobject-linkage since its logic is based on a heuristic that is not applicable to your code.
I'm using Codeblocks 13.12 with MinGW on Winodows 10. I'm somewhat familiar with C, but haven't been coding for some while. Last time I wrote a code was with Turbo compiler. So I'm starting to code once again and this the first time I'm using GCC. So I thought of starting with a simple code to print the pattern:Pattern to print
The code I wrote is:
#include<stdio.h>
using namespace std;
int main()
{
int i=0,j=0,k=0;
for(i;i<=4;++i)
{
j=2*i+1;
for(k=1;k<=j;++k)
printf(k);
}
return 0;
}
The error I get is:Error on build attempt
Tell me, is it because of some error in my code(not logical), or there's something else.
first of all there is no space after the include.
EDIT: Tried it, and it works with no space, but it's better for further reading
second, using namespace is not C, it is C++,
third, the printf function has to look like this: printf("%i",k); there has to be placeholders for each variable you want to print. please see some turorial and don't mix C and C++. If you want to program in C++ use something like cout >> instead of printf and use the C++-Headers, #include <stdio>
That works and is good to read ;-):
#include <stdio.h>
int main()
{
int i=0,j=0,k=0;
for(i;i<=4;++i)
{
j=2*i+1;
for(k=1;k<=j;++k)
printf("%i\n",k);
}
return 0;
}
I am trying to get system date in a C program on a MSVC++ 6.0 compiler. I am using a system call:
system("date /T") (output is e.g. 13-Oct-08 which is date on my system in the format i have set)
but this prints the date to the i/o console.
How do i make take this date as returned by above system call and store it as a string value to a string defined in my code?
Or
Is there any other API i can use to get the date in above mentioned format (13-Oct-08, or 13-10-08) ?
-AD
#include <windows.h>
#include <iostream>
int main() {
SYSTEMTIME systmDateTime = {};
::GetLocalTime(&systmDateTime);
wchar_t wszDate[64] = {};
int const result = ::GetDateFormatW(
LOCALE_USER_DEFAULT, DATE_SHORTDATE,
&systmDateTime, 0, wszDate, _countof(wszDate));
if (result) {
std::wcout << wszDate;
}
}
There are a couple of ways to do this using API functions, two that jump to mind are strftime and GetDateFormat.
I'd like to provide examples but I'm afraid I don't have a Win32 compiler handy at the moment. Hopefully the examples in the above documentation are sufficient.
Have a read of Win32 Time functions; GetLocalTime may be your friend. There are also the standard C time functions, time and strftime.
For future reference, in a C program, it is almost always the wrong answer to invoke an external utility and capture it's STDOUT.
Thanks for the pointers.
I used this and it served my purpose:
#include <time.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/timeb.h>
#include <string.h>
int main()
{
char tmpbuf[128];
time_t ltime;
struct tm *today;
_strdate( tmpbuf );
printf("\n before formatting date is %s",tmpbuf);
time(<ime);
today = localtime( <ime );
strftime(tmpbuf,128,"%d-%m-%y",today);
printf( "\nafter formatting date is %s\n", tmpbuf );
}
-AD