Suppose I have a structure with many members, and I pass a pointer to
that structure to a function. I'd like the prototype of the function
to specify that it will only be changing certain members of the
function, but I have only the following horrific way to do that. Can
someone please suggest a better alternative?
#include <stdio.h>
struct foo {
char *a;
char *b;
};
struct const_foo {
const char *a;
const char *b;
};
struct foo_const_a {
const char *a;
char *b;
};
struct foo_const_b {
char *a;
const char *b;
};
void modify_a(struct foo_const_b *f)
{
f->a = "a has been changed!";
}
void modify_b(struct foo_const_a *f)
{
f->b = "b has been changed!";
}
void print_foo(struc t const_foo *f)
{
printf("f.a = %s\nf.b = %s\n", f->a, f->b);
}
int main(void)
{
struct foo F = {"a string", "b string"};
print_foo((stru ct const_foo*)&F);
modify_a((struc t foo_const_b*)&F );
modify_b((struc t foo_const_a*)&F );
print_foo((stru ct const_foo*)&F);
return 0;
} 5 3323
"Bill Pursell" <bi**********@g mail.com> wrote in message
news:11******** **************@ j33g2000cwa.goo glegroups.com.. . Suppose I have a structure with many members, and I pass a pointer to that structure to a function. I'd like the prototype of the function to specify that it will only be changing certain members of the function, but I have only the following horrific way to do that. Can someone please suggest a better alternative?
#include <stdio.h>
struct foo { char *a; char *b; };
struct const_foo { const char *a; const char *b; };
struct foo_const_a { const char *a; char *b; };
struct foo_const_b { char *a; const char *b; };
void modify_a(struct foo_const_b *f) { f->a = "a has been changed!"; }
void modify_b(struct foo_const_a *f) { f->b = "b has been changed!"; }
void print_foo(struc t const_foo *f) { printf("f.a = %s\nf.b = %s\n", f->a, f->b); }
int main(void) { struct foo F = {"a string", "b string"};
print_foo((stru ct const_foo*)&F); modify_a((struc t foo_const_b*)&F ); modify_b((struc t foo_const_a*)&F ); print_foo((stru ct const_foo*)&F);
return 0; }
Since modify_b can't modify 'a' and modify_a can't modify 'b', why do you
need to protect the other structure elements? Is there a data corruption
issue here?
If so, you might want to have two versions of the structure: "protected" and
"unprotecte d". At a critical point in the program, copy the "protected"
structure to the "unprotecte d" one. Modify elements of the "unprotecte d"
structure via a normal routine or assignment. When done, you have a few
choices. You could discard the "unprotecte d" structure, copy the
"unprotecte d" structure to the "protected" one, copy the modified element
from the "unprotecte d" structure to the "protected" , or compare the
structures to see what's going wrong.
Rod Pemberton
On 1 May 2006 12:19:48 -0700, "Bill Pursell" <bi**********@g mail.com>
wrote: Suppose I have a structure with many members, and I pass a pointer to that structure to a function. I'd like the prototype of the function to specify that it will only be changing certain members of the function, but I have only the following horrific way to do that. Can someone please suggest a better alternative?
#include <stdio.h>
struct foo { char *a; char *b; };
struct const_foo { const char *a; const char *b; };
struct foo_const_a { const char *a; char *b; };
struct foo_const_b { char *a; const char *b; };
void modify_a(struct foo_const_b *f) { f->a = "a has been changed!"; }
void modify_b(struct foo_const_a *f) { f->b = "b has been changed!"; }
void print_foo(struc t const_foo *f) { printf("f.a = %s\nf.b = %s\n", f->a, f->b); }
int main(void) { struct foo F = {"a string", "b string"};
print_foo((stru ct const_foo*)&F);
Unfortunately, this need not work. You have no guarantee that the
padding, or lack of same, in a struct foo is the same as that in a
struct const_foo). offsetof(struct foo,b) could be 4 while
offsetof(struct const_foo,b) could be 8. Unlikely, I admit, but still
possible, especially on the DS9000. modify_a((struc t foo_const_b*)&F ); modify_b((struc t foo_const_a*)&F ); print_foo((stru ct const_foo*)&F);
return 0; }
Remove del for email
Rod Pemberton wrote: "Bill Pursell" <bi**********@g mail.com> wrote in message news:11******** **************@ j33g2000cwa.goo glegroups.com.. . Suppose I have a structure with many members, and I pass a pointer to that structure to a function. I'd like the prototype of the function to specify that it will only be changing certain members of the function, but I have only the following horrific way to do that. Can someone please suggest a better alternative?
#include <stdio.h>
struct foo { char *a; char *b; };
struct const_foo { const char *a; const char *b; };
struct foo_const_a { const char *a; char *b; };
struct foo_const_b { char *a; const char *b; };
void modify_a(struct foo_const_b *f) { f->a = "a has been changed!"; }
void modify_b(struct foo_const_a *f) { f->b = "b has been changed!"; }
void print_foo(struc t const_foo *f) { printf("f.a = %s\nf.b = %s\n", f->a, f->b); }
int main(void) { struct foo F = {"a string", "b string"};
print_foo((stru ct const_foo*)&F); modify_a((struc t foo_const_b*)&F ); modify_b((struc t foo_const_a*)&F ); print_foo((stru ct const_foo*)&F);
return 0; }
Since modify_b can't modify 'a' and modify_a can't modify 'b', why do you need to protect the other structure elements? Is there a data corruption issue here?
There's no data corruption problem, I just observed that in many
instances I have data structures with several buffers getting passed
into functions, and the only manner by which I can tell which function
modifies which buffer is to inspect the function body/comments. I
could modify the protoypes to specify that the struct is constant, but
that of course gives no assurance on the contents of foo->a. I suppose
the only other solution is to define the structure as having const
members and making it difficult to assign/modify things. Something
like:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct foo {
const char *a;
const char *b;
};
void
print_foo(const struct foo *f)
{
printf("f.a = %s\n", f->a);
printf("f.b = %s\n", f->b);
}
void
modify(const struct foo *f, char *dest)
{
const char *src = f->a;
dest[0] = src[0]+1;
}
int
main(void)
{
struct foo f;
f.a = malloc(20);
f.b = malloc(20);
if (f.a == NULL || f.b == NULL)
perror(0), exit(-1);
strcpy((char *)f.a, "string a");
strcpy((char *)f.b, "string b");
print_foo(&f);
modify(&f, (char *)f.b);
print_foo(&f);
return 0;
}
The trouble with this is that modify() (or print_foo()!) could be still
be written to do:
((char *)f->a)[3]++;
but that's pathologically poor coding, so I can avoid that. In this
instance, the caller is doing all the casting, so it's fairly clear
from context which members are being modified.
"Bill Pursell" <bi**********@g mail.com> wrote in message
news:11******** **************@ g10g2000cwb.goo glegroups.com.. . Rod Pemberton wrote: "Bill Pursell" <bi**********@g mail.com> wrote in message news:11******** **************@ j33g2000cwa.goo glegroups.com.. . Suppose I have a structure with many members, and I pass a pointer to that structure to a function. I'd like the prototype of the function to specify that it will only be changing certain members of the function, but I have only the following horrific way to do that. Can someone please suggest a better alternative?
Since modify_b can't modify 'a' and modify_a can't modify 'b', why do
you need to protect the other structure elements? Is there a data
corruption issue here?
There's no data corruption problem, I just observed that in many instances I have data structures with several buffers getting passed into functions, and the only manner by which I can tell which function modifies which buffer is to inspect the function body/comments. I could modify the protoypes to specify that the struct is constant, but that of course gives no assurance on the contents of foo->a. I suppose the only other solution is to define the structure as having const members and making it difficult to assign/modify things. Something like:
It seems that you are trying to create C features with may be available in
C++. I know very little about C++, but IIRC, you can implement data
protection due to the object oriented feature of binding code with data.
The code gets executed for each action on the data. Which means, you can
prevent variables from being multiply assigned, set, reset or whatever...
Perhaps you might look into using a small amount of C++.
Rod Pemberton
On 1 May 2006 12:19:48 -0700, "Bill Pursell" <bi**********@g mail.com>
wrote: Suppose I have a structure with many members, and I pass a pointer to that structure to a function. I'd like the prototype of the function to specify that it will only be changing certain members of the function, but I have only the following horrific way to do that. Can someone please suggest a better alternative?
#include <stdio.h>
struct foo { char *a; char *b; };
struct const_foo { const char *a; const char *b; };
struct foo_const_a { const char *a; char *b; };
struct foo_const_b { char *a; const char *b; };
void modify_a(struct foo_const_b *f) { f->a = "a has been changed!"; }
void modify_b(struct foo_const_a *f) { f->b = "b has been changed!"; }
Those don't (even) do what you asked for. What you declared const is
the data pointed to by the struct member e.g. a, not the member a
itself. In your modify_a (struct foo_const_b *f)
f->b = something would work with no (required) complaint.
You wanted
struct foo_const_a { char * const a; char * b; };
etc.
As already noted, formally these 'slightly different' structs are not
required to be 'compatible' i.e. laid out the same, although I don't
see any plausible reason an implementation would not do so.
And as you already noted, there is nothing to prevent the called
routine from casting away these 'partial consts', so in general you're
going to have to read the code of those functions anyway. Ideally you
(or whoever) should give the functions, and sometimes their
interface/prototype parameters, names that accurately describe what
they do, so just by looking at them you can tell. That's not always
easy to do however, especially in code that has evolved (and often
deteriorated) over time, changes, and (supposed) enhancements.
If the routines/library you are calling are in really bad shape, you
might be better off just rewriting up to scratch. Your call.
- David.Thompson1 at worldnet.att.ne t This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics |
by: Thomas Matthews |
last post by:
Hi,
Given a structure of pointers:
struct Example_Struct
{
unsigned char * ptr_buffer;
unsigned int * ptr_numbers;
};
And a function that will accept the structure:
|
by: kelvSYC |
last post by:
If you have an instance of a struct that's marked const, does the const
keyword mean that all of its members are read-only? What if you wanted
a struct where some members are constants and a few others you could
change?
Example:
struct foo {
const int a;
int b;
|
by: S.Tobias |
last post by:
1. If I have a struct type which contains a const member:
struct mystruct
{
const int id;
int mutable;
};
does a definition
struct mystruct ms;
define an object `ms' which is *partly* const? Ie. the object `ms'
is not const as a whole, but modifying ms.id yields UB in all contexts?
|
by: dj |
last post by:
Perhaps this question should be in the standard c newsgroup, but i hope
somebody answers it here. Anyway, I came across this situation in an
otherwise c++ code.
I need a struct that works like some sort of a flag set. The flag mask
is a single long, while the meaning of individual flags is given by
static const members of the same struct:
struct flag_set {
long flags;
|
by: subramanian100in |
last post by:
The following is a beginner's question.
Suppose TYPE1 and TYPE2 are two types for which suitable ctors and
operator= are defined.
Suppose I have
class Test
{
TYPE1 mem1;
| |
by: subramanian100in |
last post by:
Consider the following program:
#include <iostream>
using namespace std;
class Base
{
public:
Base(int x = 0);
|
by: hweekuan |
last post by:
hi,
it seems i can't assign the const variable u in class A, one way to
solve the problem may be to build a copy constructor. however, why
does C++ or vector class not like this code? my g++ is: gcc version
4.0.1 (Apple Inc. build 5465). thanks for the help.
summary of compile error:
---------------------------------------
cpp.C:4: error: non-static const member 'const unsigned int A::u',
|
by: akomiakov |
last post by:
Is there a technical reason why one can't initialize a cost static non-
integral data member in a class?
|
by: Hystou |
last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it.
First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
|
by: Oralloy |
last post by:
Hello folks,
I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>".
The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed.
This is as boiled down as I can make it.
Here is my compilation command:
g++-12 -std=c++20 -Wnarrowing bit_field.cpp
Here is the code in...
|
by: Hystou |
last post by:
Overview:
Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
| |
by: tracyyun |
last post by:
Dear forum friends,
With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
|
by: isladogs |
last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM).
In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules.
He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms.
Adolph will...
|
by: adsilva |
last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
|
by: 6302768590 |
last post by:
Hai team
i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
|
by: muto222 |
last post by:
How can i add a mobile payment intergratation into php mysql website.
|
by: bsmnconsultancy |
last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...
| |