Why does struct have two variable names in C/C++ - c++

In the below code why does the struct have two variable names?
#include <sys/resource.h>
int main (int argc, char **argv)
{
const rlim_t kStackSize = 64L * 1024L * 1024L;
struct rlimit rl; //HERE
int result = getrlimit(RLIMIT_STACK, &rl);
return 0;
}

In C, struct with its tag together is a name, unless it's typedefed.
In C++, you can omit the struct keyword.

If this is C, the struct is just to tell C that it is in a different namespace.
See: understanding C namespaces
If this is C+++, then the struct is not needed.

Related

Why can't some types (with array notation) be used as return type in C without typedef?

While messing around with the type syntax, I noticed this is legal :
typedef int *((* T)[10]);
T fun(){
return 0;
};
int main(int argc, char * argv[]){
//int c = fun(); // (1)
return 0;
}
...And if you uncomment (1), then you get an error message of this kind (GCC / Clang) : "error: cannot initialize a variable of type 'int' with an rvalue of type 'T' (aka 'int *((*)[10])')" (Normal so far). Notice however the "aka" that points out the type is an alias of int *((*)[10]) and not simply int ***
However, It seems impossible to declare a function with this type without using a typedef :
int *((*)[10]) fun(){ // The compiler does not approve
return 0;
};
int *((* fun2)[10]) (){ // The compiler does not approve either
return 0;
};
int main(int argc, char * argv[]){
//int c = fun(); // (1)
return 0;
}
...Then I was wondering why ?
(the question is for the C language, but it looks like it's the same for C++)
This type:
typedef int *((* T)[10]);
Is a pointer to an array of size 10 whose members are of type int *. This is not the same as an int ***.
As for creating a function that returns this type, you would need this:
int *(*fun())[10] {
return 0;
};
But using a typedef makes this much clearer.
int *((*fun())[10]) {
return 0;
};
... Yup. You should probably stick to the typedef for the sake of readability :)
The original
typedef int *((* T)[10])
can shed the outer parens:
typedef int *(* T)[10]
Or aligned with dbush's function:
typedef int *(* T )[10]
int *(* fun() )[10]

Process Exit: value 3221225477

When I am adding
local_w_p_n->wp_val_p = rx_pbuf;
local_w_p_n->wp_val_n = rx_netif;
in rx_local_p_n function to the program code, the code is compiled but running in Process Exit: value 3221225477. Does anyone know why and how to fix it?
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
struct pbuf{
int a;
int b;
};
struct netif{
int c;
int d;
};
struct wrapper_p_n{ // wrapper for pbuf- and netif-struct pointer
struct pbuf *wp_val_p;
struct netif *wp_val_n;
};
void rx_local_p_n(struct pbuf *rx_pbuf, struct netif *rx_netif)
{
// wrap the received pointer
struct wrapper_p_n *local_w_p_n;
local_w_p_n->wp_val_p = rx_pbuf;
local_w_p_n->wp_val_n = rx_netif;
printf("rx_local_p_n\n");
//Passing *local_w_p_n pointer to another function
//check_value(local_w_p_n);
}
int main(int argc, char** argv) {
// give values to local_pbuf and netif
struct pbuf local_pbuf;
local_pbuf.a = 1;
local_pbuf.b = 2;
struct netif local_netif;
local_netif.c = 3;
local_netif.d = 4;
//passing pbuf- and netif-stuct to function
rx_local_p_n(&local_pbuf, &local_netif);
printf("return\n");
return 0;
}
struct wrapper_p_n *local_w_p_n;
local_w_p_n->wp_val_p = rx_pbuf;
local_w_p_n->wp_val_n = rx_netif;
local_w_p_n is an uninitalised pointer, and dereferencing it is liable to cause your program to crash.
Judging by the commented out code, what you are really looking for is this
struct wrapper_p_n local_w_p_n;
local_w_p_n.wp_val_p = rx_pbuf;
local_w_p_n.wp_val_n = rx_netif;
//Passing pointer to local_w_p_n to another function
check_value(&local_w_p_n);
Instead of declaring a pointer, the code above declares a regular variable, and then uses the address-of operator & to obtain a pointer to that variable.
In fact you wrote exactly the same code in main, so not sure why you tried something different here.

Objective-C Block Literal Syntax Principle

i'm a iOS programer from china, I'm so sorry that i can't make an exact title for this question, but i'll try to describe it detailed. If there are any one can help me to change the title, i'm very thankful about that. Sorry for my bad English.
When i using clang -rewrite-objc to see the source code about the Block Syntax, i found there is something that i can't understand. Here is my code:
int main(int argc, char *argv[]) {
void (^blk)() = ^ {
};
blk();
}
And the core source code is
struct __block_impl {
void *isa;
int Flags;
int Reserved;
void *FuncPtr;
};
struct __main_block_impl_0 {
struct __block_impl impl;
struct __main_block_desc_0* Desc;
__main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, int flags=0) {
impl.isa = &_NSConcreteStackBlock;
impl.Flags = flags;
impl.FuncPtr = fp;
Desc = desc;
}
};
static void __main_block_func_0(struct __main_block_impl_0 *__cself) {
}
static struct __main_block_desc_0 {
size_t reserved;
size_t Block_size;
} __main_block_desc_0_DATA = { 0, sizeof(struct __main_block_impl_0)};
int main(int argc, char *argv[]) {
void (*blk)() = ((void (*)())&__main_block_impl_0((void *)__main_block_func_0, &__main_block_desc_0_DATA));
((void (*)(__block_impl *))((__block_impl *)blk)->FuncPtr)((__block_impl *)blk);
}
In the main function, when i call the blk(), the source code cast blk and take the FuncPtr by this code
((__block_impl *)blk)->FuncPtr)
I can't really understand that, is it supposed to do? In my opinion, i prefer to use
(((__main_block_impl_0 *)blk ->impl).FuncPtr)
I don't really know more about C++, if there is anyone who can help me to understand the principle of this code, i'll be very thankful. Thanks for you guys.
Well, struct __main_block_impl_0's first member (impl) is a struct __block_impl. So the location of the struct __main_block_impl_0 is the same as the location of the struct __block_impl that is its first member. If you have the pointer to one you can just treat it as a pointer to the other.

Expose private internal class size

I need to expose a compile time constant with the size of internal class. To do so I tried next code:
#include <cassert>
struct A
{
//consider Private class as private for this example, just to be able to put the assert like this in main
class Private{};
enum { PrivateSize = sizeof(Private) };
};
int main()
{
//here I have warning on some compilers, signed/unsigned comparison
assert(A::PrivateSize == sizeof(A::Private));
}
My problem is that PrivateSize is signed on some compiler and unsigned on others and I get warnings about this when comparing it with signed types. As far as I know enum's underlying type is implementation defined and can't be forced to be signed or unsigned.
Do you know a way to expose sizeof(A::Private) outside A as compile time constant, but keeping Private class... private? Please note I can't use constexpr as the code will be used on some old compilers.
Following works:
struct A
{
friend int main(int argc, char *argv[]); // For test purpose
private:
class Private{};
public:
static const unsigned int PrivateSize = sizeof (Private);
};
int main(int argc, char *argv[])
{
assert(A::PrivateSize == sizeof(A::Private));
return 0;
}

Access reading error when using class member variable

I have a class with private member variables declared in a header file. In my constructor, I pass in some filenames and create other objects using those names. This works fine. When I try to add another member variable, however, and initialize it in the constructor, I get an access reading violation. I sent the code to someone else and it works fine on his computer. Any idea what could be wrong?
Here is the offending code:
The .h file:
class QUERYMANAGER {
INDEXCACHE *cache;
URLTABLE *table;
SNIPPET *snip;
int* iquery[MAX_QUERY_LENGTH];
int* metapointers[MAX_QUERY_LENGTH];
int blockpointers[MAX_QUERY_LENGTH];
int docpositions[MAX_QUERY_LENGTH];
int numberdocs[MAX_QUERY_LENGTH];
int frequencies[MAX_QUERY_LENGTH];
int docarrays[MAX_QUERY_LENGTH][256];
int qsize;
public:
QUERYMANAGER();
QUERYMANAGER(char *indexfname, char *btfname, char *urltablefname, char *snippetfname, char *snippetbtfname);
~QUERYMANAGER();
This is the .cpp file:
#include "querymanagernew.h"
#include "snippet.h"
using namespace std;
QUERYMANAGER::QUERYMANAGER(char *indexfname, char *btfname, char *urltablefname, char *snippetfname, char *snippetbtfname){
cache = new INDEXCACHE(indexfname, btfname);
table = new URLTABLE(urltablefname);
snip = new SNIPPET(snippetfname, snippetbtfname);
//this is where the error occurs
qsize = 0;
}
I am totally at a loss as to what is causing this - any ideas?
Thanks, bsg
Suggestion, factor out the arrays:
class QUERYMANAGER
{
// Snip
int* iquery[MAX_QUERY_LENGTH];
int* metapointers[MAX_QUERY_LENGTH];
int blockpointers[MAX_QUERY_LENGTH];
int docpositions[MAX_QUERY_LENGTH];
int numberdocs[MAX_QUERY_LENGTH];
int frequencies[MAX_QUERY_LENGTH];
int docarrays[MAX_QUERY_LENGTH][256];
int qsize;
// Snip
};
Looks like you should have another structure:
struct Info
{
int* iquery;
int* metapointers;
int blockpointers;
int docpositions;
int numberdocs;
int frequencies;
int docarrays[256];
};
And the QueryManager now looks like:
class QueryManager
{
INDEXCACHE *cache;
URLTABLE *table;
SNIPPET *snip;
int qsize;
Info details[MAX_QUERY_LENGTH];
};
This may help encapsulate themes a little better.
Your dependencies are probably not right, and the necessary files aren't getting rebuilt. Try a "clean" rebuild.
As a note to style, use initializer lists.
QUERYMANAGER::QUERYMANAGER(char *indexfname, char *btfname, char *urltablefname,
char *snippetfname, char *snippetbtfname) :
cache(new INDEXCACHE(indexfname, btfname)),
table(new URLTABLE(urltablefname)),
snip(new SNIPPET(snippetfname, snippetbtfname)),
qsize(0)
{
}
and you may not need to make those items pointers:
class QUERYMANAGER {
INDEXCACHE cache;
URLTABLE table;
SNIPPET snip;
...
QUERYMANAGER::QUERYMANAGER(char *indexfname, char *btfname, char *urltablefname,
char *snippetfname, char *snippetbtfname) :
cache(indexfname, btfname),
table(urltablefname),
snip(snippetfname, snippetbtfname),
qsize(0)
{
}
Have you built clean? Since accessing the last member variable blows up, but assigning to earlier ones works OK, either you're not constructing/allocating the instance right when you do use it, or you have object files that refer to older versions of the header that didn't have qsize in the object yet, and thus aren't allocating enough space. Or something along those lines.
As expected, this runs just fine on my machine:
#include <cstdlib>
struct INDEXCACHE {};
struct URLTABLE {};
struct SNIPPET {};
const std::size_t MAX_QUERY_LENGTH = 256;
class QUERYMANAGER {
INDEXCACHE *cache;
URLTABLE *table;
SNIPPET *snip;
int* iquery[MAX_QUERY_LENGTH];
int* metapointers[MAX_QUERY_LENGTH];
int blockpointers[MAX_QUERY_LENGTH];
int docpositions[MAX_QUERY_LENGTH];
int numberdocs[MAX_QUERY_LENGTH];
int frequencies[MAX_QUERY_LENGTH];
int docarrays[MAX_QUERY_LENGTH][256];
int qsize;
public:
QUERYMANAGER(char *indexfname, char *btfname, char *urltablefname, char *snippetfname, char *snippetbtfname);
};
QUERYMANAGER::QUERYMANAGER(char *indexfname, char *btfname, char *urltablefname, char *snippetfname, char *snippetbtfname)
: cache(new INDEXCACHE(/*indexfname, btfname*/))
, table(new URLTABLE(/*urltablefname*/))
, snip(new SNIPPET(/*snippetfname, snippetbtfname*/))
, qsize(0)
{
}
int main()
{
QUERYMANAGER foo("blargl", "frxnl", "wrgxl", "brlgl", "srgl");
return 0;
}
So the error must be in the code you're not showing.
BTW, all upper-case names are boo except for macros. They're making your code harder to read and confuse everyone used to a more common coding style.