473,508 Members | 2,392 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

const does not apply to pointers?

When accessing pointer member variables these are not treated as const
even though the instance is const. This came as a complete surprise to
me and I would appreciate some feedback why that is the case.
Here's a snippet:

class MyClass {
public:
char *pChar;
};
void ChangePointedTo (char *ch)
{
*ch = 0;
}
void DoStuff (const MyClass &constClass)
{
ChangePointedTo ( constClass.pChar ); // <-- why does this work?
}

I would have expected a compiler error telling me that
"constClass.pChar" is of type "const char *" but instead it gets passed
to the function without any problems and suddenly MyClass is not so
const anymore...

Aug 29 '06 #1
23 2062
gr******@gmail.com wrote:
When accessing pointer member variables these are not treated as const
even though the instance is const. This came as a complete surprise to
me and I would appreciate some feedback why that is the case.
Here's a snippet:

class MyClass {
public:
char *pChar;
};
void ChangePointedTo (char *ch)
{
*ch = 0;
}
void DoStuff (const MyClass &constClass)
{
ChangePointedTo ( constClass.pChar ); // <-- why does this work?
}

I would have expected a compiler error telling me that
"constClass.pChar" is of type "const char *" but instead it gets passed
to the function without any problems and suddenly MyClass is not so
const anymore...
You have confused a "const char*" with "char* const". Please take a
look at the FAQ:

http://www.parashift.com/c++-faq-lit....html#faq-18.5

Best regards,

Tom

Aug 29 '06 #2
In article <11*********************@75g2000cwc.googlegroups.c om>,
gr******@gmail.com wrote:
When accessing pointer member variables these are not treated as const
even though the instance is const. This came as a complete surprise to
me and I would appreciate some feedback why that is the case.
Here's a snippet:

class MyClass {
public:
char *pChar;
};
void ChangePointedTo (char *ch)
{
*ch = 0;
}
void DoStuff (const MyClass &constClass)
{
ChangePointedTo ( constClass.pChar ); // <-- why does this work?
}

I would have expected a compiler error telling me that
"constClass.pChar" is of type "const char *"
It's not "const char *", it's "char * const" which of course *can* be
passed to ChangePointerTo.
Aug 29 '06 #3
gr******@gmail.com wrote:
When accessing pointer member variables these are not treated as const
even though the instance is const. This came as a complete surprise to
me and I would appreciate some feedback why that is the case.
Here's a snippet:

class MyClass {
public:
char *pChar;
};
void ChangePointedTo (char *ch)
{
*ch = 0;
}
void DoStuff (const MyClass &constClass)
{
ChangePointedTo ( constClass.pChar ); // <-- why does this work?
}

I would have expected a compiler error telling me that
"constClass.pChar" is of type "const char *" but instead it gets passed
to the function without any problems and suddenly MyClass is not so
const anymore...
This is one of the drawbacks of C++. Since the compiler can only ensure
that the binary representation of the object doesn't change, you may
change objects that are pointed to (since you don't change values of the
pointer, the 'binary' constness of your constant object is satisfied).

This logic is only expected, since it makes the compiler so much
simpler. You can avoid this pitfall by providing a proper interface to
your object (permitting access to a member variable is considered bad
style by the majority of C++ programmers):

#include <stdio.h>

class MyClass {
protected:
char *pChar; // Member variable is now protected.
public:
char *GetpChar () { // Accessor for pChar.
return pChar;
}
const char* GetpChar () const { // Another accessor for pChar
return pChar; // that gets invoked for const objects.
}
};

void ChangePointedTo (char *ch)
{
*ch = 0;
}

void UsePointedTo (const char* ch)
{
printf (ch);
}

void DoStuff (const MyClass& constClass)
{
ChangePointedTo ( constClass.GetpChar ()); // this doesn't work anymore
}

void DoStuff2 (MyClass& non_constClass)
{
ChangePointedTo ( non_constClass.GetpChar ()); // this works
}

void DoStuff3 (const MyClass& constClass)
{
UsePointedTo ( constClass.GetpChar ()); // this works also
}

Regards,
Stuart
Aug 29 '06 #4
I did a short skit on some of the vagaries of const for The Register
http://www.regdeveloper.co.uk/2006/0...tants_are_not/
DominiConnor
DCFC The Pimp
Stuart Redmann wrote:
gr******@gmail.com wrote:
When accessing pointer member variables these are not treated as const
even though the instance is const. This came as a complete surprise to
me and I would appreciate some feedback why that is the case.
Here's a snippet:

class MyClass {
public:
char *pChar;
};
void ChangePointedTo (char *ch)
{
*ch = 0;
}
void DoStuff (const MyClass &constClass)
{
ChangePointedTo ( constClass.pChar ); // <-- why does this work?
}

I would have expected a compiler error telling me that
"constClass.pChar" is of type "const char *" but instead it gets passed
to the function without any problems and suddenly MyClass is not so
const anymore...

This is one of the drawbacks of C++. Since the compiler can only ensure
that the binary representation of the object doesn't change, you may
change objects that are pointed to (since you don't change values of the
pointer, the 'binary' constness of your constant object is satisfied).

This logic is only expected, since it makes the compiler so much
simpler. You can avoid this pitfall by providing a proper interface to
your object (permitting access to a member variable is considered bad
style by the majority of C++ programmers):

#include <stdio.h>

class MyClass {
protected:
char *pChar; // Member variable is now protected.
public:
char *GetpChar () { // Accessor for pChar.
return pChar;
}
const char* GetpChar () const { // Another accessor for pChar
return pChar; // that gets invoked for const objects.
}
};

void ChangePointedTo (char *ch)
{
*ch = 0;
}

void UsePointedTo (const char* ch)
{
printf (ch);
}

void DoStuff (const MyClass& constClass)
{
ChangePointedTo ( constClass.GetpChar ()); // this doesn't work anymore
}

void DoStuff2 (MyClass& non_constClass)
{
ChangePointedTo ( non_constClass.GetpChar ()); // this works
}

void DoStuff3 (const MyClass& constClass)
{
UsePointedTo ( constClass.GetpChar ()); // this works also
}

Regards,
Stuart
Aug 29 '06 #5
gr******@gmail.com wrote:
When accessing pointer member variables these are not treated as const
even though the instance is const. This came as a complete surprise to
me and I would appreciate some feedback why that is the case.
Here's a snippet:

class MyClass {
public:
char *pChar;
};
void ChangePointedTo (char *ch)
{
*ch = 0;
}
ch is const. The thing it points to is not. So you can change *ch, but
you can't change ch. Try it:

ch = 0; // illegal
Aug 29 '06 #6
Stuart Redmann wrote:
gr******@gmail.com wrote:
>When accessing pointer member variables these are not treated as const
even though the instance is const. This came as a complete surprise to
me and I would appreciate some feedback why that is the case.
Here's a snippet:

class MyClass {
public:
char *pChar;
};
void ChangePointedTo (char *ch)
{
*ch = 0;
}
void DoStuff (const MyClass &constClass)
{
ChangePointedTo ( constClass.pChar ); // <-- why does this work?
}

I would have expected a compiler error telling me that
"constClass.pChar" is of type "const char *" but instead it gets passed
to the function without any problems and suddenly MyClass is not so
const anymore...

This is one of the drawbacks of C++. Since the compiler can only ensure
that the binary representation of the object doesn't change, you may
change objects that are pointed to (since you don't change values of the
pointer, the 'binary' constness of your constant object is satisfied).
It's not a drawback. If you want to say that the thing that's pointed to
can't be changed through this pointer, mark it const:

const char *pChar;
Aug 29 '06 #7

Stuart Redmann wrote:
gr******@gmail.com wrote:
When accessing pointer member variables these are not treated as const
even though the instance is const. This came as a complete surprise to
me and I would appreciate some feedback why that is the case.
Here's a snippet:
<snip>

use string or vector<charas the member instead of const char * and it
would work as desired.

There is no formal concept of ownership in C++ with regards to
pointers. If we talk about the state of a class changing, that should
also indicate anything it has ownership of, but not anything it simply
has reference of.

You cannot guarantee therefore that if T is a class and x() is a
const-method, then calling x() twice in succession will give the same
result even if there are no other threads because although the T won't
change, there may be other classes that change when you call x(). const
method doesn't mean change nothing.

Now I think Herb Sutter even addressed this issue at some point with
regards to propagating constness and there were proposals for different
levels of const. I think it was decided that whilst it might be useful
it made const-correctness even more difficult than it is now and would
make life too difficult for programmers to use.

The problem is more likely to sort itself out with the increasing use
of smart-pointers. It is a good idea in my opinion to implement those
smart-pointers that take ownership of their pointer (not shared_ptr
which only has shared ownership) to propagate constness. For smart
pointers that use a boolean flag to indicate ownership, I think this
would be impossible as it's a compiler error we are looking for, not a
runtime one. Of course this would probably lead whoever implements such
smart pointers to end up using two variations of templates with a
boolean-value template parameter (I've seen boost do that for traits
etc).

Aug 29 '06 #8
Pete Becker wrote:
gr******@gmail.com wrote:
>When accessing pointer member variables these are not treated as const
even though the instance is const. This came as a complete surprise to
me and I would appreciate some feedback why that is the case.
Here's a snippet:

class MyClass {
public:
char *pChar;
};
void ChangePointedTo (char *ch)
{
*ch = 0;
}


ch is const. The thing it points to is not. So you can change *ch, but
you can't change ch. Try it:

ch = 0; // illegal
Whoops, it's pChar that's const:

pChar = 0; // illegal

To prevent changing the char that it points to, make it a pointer to const:

const char *pChar;

Aug 29 '06 #9
gr******@gmail.com wrote:
When accessing pointer member variables these are not treated as const
even though the instance is const. This came as a complete surprise to
me and I would appreciate some feedback why that is the case.
Here's a snippet:

class MyClass {
public:
char *pChar;
};
void ChangePointedTo (char *ch)
{
*ch = 0;
}
void DoStuff (const MyClass &constClass)
{
ChangePointedTo ( constClass.pChar ); // <-- why does this work?
}

I would have expected a compiler error telling me that
"constClass.pChar" is of type "const char *" but instead it gets passed
to the function without any problems and suddenly MyClass is not so
const anymore...
Calling DoStuff doesn't change anything in your const object. pChar
points to something outside the object, and the code doesn't say that
the thing it points to shouldn't be modified. The type of
constClass.pChar is char *const, not const char *. To make it const
char*, define it that way:

const char *pChar;
Aug 29 '06 #10
Thanks for all the feedback !
I was assuming that const'ing an object would basically prepend a
"const" to its members, as in:
char member1; becomes const char member1;
and
char* member2; becomes const char* member2;

Instead it can be visualized as appending the const:
char member1; becomes char const member1;
and
char* member2; becomes char* const member2;

The suggestion of adding a const in the class definition works for this
example but I can't use it in the real-life case where I ran into this
issue. Using accessors might be a viable solution though.

Aug 29 '06 #11
gr******@gmail.com wrote:
Thanks for all the feedback !
I was assuming that const'ing an object would basically prepend a
"const" to its members, as in:
char member1; becomes const char member1;
and
char* member2; becomes const char* member2;

Instead it can be visualized as appending the const:
char member1; becomes char const member1;
and
char* member2; becomes char* const member2;
Actually it is NEITHER. It makes each member const.
You need to learn how declarations work or you're going
to be in for a world of grief.

What about
int (*member3)(char*, int);
???
The suggestion of adding a const in the class definition works for this
example but I can't use it in the real-life case where I ran into this
issue. Using accessors might be a viable solution though.
Huh? Do you know the difference between a pointer being const and
the object it points to being const?
Aug 29 '06 #12

gr******@gmail.com wrote:
Thanks for all the feedback !
I was assuming that const'ing an object would basically prepend a
"const" to its members, as in:
char member1; becomes const char member1;
and
char* member2; becomes const char* member2;

Instead it can be visualized as appending the const:
char member1; becomes char const member1;
and
char* member2; becomes char* const member2;

The suggestion of adding a const in the class definition works for this
example but I can't use it in the real-life case where I ran into this
issue. Using accessors might be a viable solution though.
It is for reasons like this that I have stopped using prefix const
notation. Even though it speaks better, "a constant int pointer," it
creates inconsistancies such as this. So now I say, "an int that is
contstant pointer."

Aug 29 '06 #13
Noah Roberts wrote:
It is for reasons like this that I have stopped using prefix const
notation. Even though it speaks better, "a constant int pointer," it
creates inconsistancies such as this. So now I say, "an int that is
contstant pointer."
What? "an int that is a pointer?"
Ints aren't pointers.

How about a "pointer that is constant to int"

Aug 29 '06 #14
gr******@gmail.com wrote:
Thanks for all the feedback !
I was assuming that const'ing an object would basically prepend a
"const" to its members, as in:
char member1; becomes const char member1;
and
char* member2; becomes const char* member2;

Instead it can be visualized as appending the const:
char member1; becomes char const member1;
and
char* member2; becomes char* const member2;

The suggestion of adding a const in the class definition works for this
example but I can't use it in the real-life case where I ran into this
issue. Using accessors might be a viable solution though.
As others suggested, you can use other containers (e.g., std::vector)
that propogate constness to their containees. You can also implement a
pointer proxy class that propogates constness to its pointee. Something
like:

struct MyException {};

template <class T>
class DeepPtr
{
public:
DeepPtr( T* const ptr )
: m_ptr( ptr )
{
if( !ptr )
{
throw MyException(); // or whatever
}
}

// Standard access
T* operator->() { return m_ptr; }
T& operator*() { return *m_ptr; }

// Make pointee const if pointer is const
const T* operator->() const { return m_ptr; }
const T& operator*() const { return *m_ptr; }

private:
T * const m_ptr;

// Disabled copying
DeepPtr( const DeepPtr& );
DeepPtr& operator=( const DeepPtr& );
};

class A
{
DeepPtr<intm_pi1;
int *const m_pi2
public:
A( int* const pi1, int* const pi2 )
: m_pi1( pi1 ), m_pi2( pi2 )
{
*m_pi1 = 0xEATBEEF;
*m_pi2 = 0xEATBEEF;
}

void Foo() const
{
*m_pi1 = 0xFEEDB0B; // Error!
*m_pi2 = 0xFEEDB0B; // Ok
}

void Foo()
{
*m_pi1 = 0xC0FFEE; // Ok
*m_pi2 = 0xC0FFEE; // Ok
}
};

The copy constructor and assignment operator are disable because they
would allow a backdoor to ignore constness (intentionally or not), and
as a result, this pointer proxy is not usable in standard containers
such as std::vector that require copy construction. It also means that
the example class A can't be copied either, but that may be acceptable
for your application.

Cheers! --M

Aug 30 '06 #15

Ron Natalie wrote:
Noah Roberts wrote:
It is for reasons like this that I have stopped using prefix const
notation. Even though it speaks better, "a constant int pointer," it
creates inconsistancies such as this. So now I say, "an int that is
contstant pointer."
What? "an int that is a pointer?"
Note that that is a rewording of my actual statement, one that is
iscompatible with the original.
Ints aren't pointers.
Thanks for the info.
>
How about a "pointer that is constant to int"
Yeah, that doesn't match the source code. The point I was making is
that "const int *" ends up reading like "constant int pointer." The
other way, "int const *," ends up reading, "int that is constant
pointer." Your statement would be equivelant to "* const int," and
that is a syntax error. It is also not equivelant to "const int *" as
it would be more akin to "int * const" or "an int pointer that is
constant."

Aug 30 '06 #16
Noah Roberts wrote:
>
Yeah, that doesn't match the source code.
Once you get past a trivial declaration you're not going
to be able to linearly translate into something lexically
symentric. I say:
const char STAR foo
If I'm reading the code, but if I'm describing the
type I say
pointer to const char.

Trying to say something like

int *(*foo)(const char*, int(*)());

is just going to be gibberish read left to right.
Aug 30 '06 #17
do************@gmail.com wrote:
I did a short skit on some of the vagaries of const for The Register
http://www.regdeveloper.co.uk/2006/0...tants_are_not/
You call it a "skit", implying it is a joke. This is appropriate, since
it is almost completely factually incorrect. But if an average person
with only a modest familiarity with C++ were to read the article,
they could well take it seriously.

Aug 31 '06 #18

mlimber wrote:
template <class T>
class DeepPtr
{
public:
DeepPtr( T* const ptr )
: m_ptr( ptr )
{
if( !ptr )
{
throw MyException(); // or whatever
}
I'd prefer to allow such pointers to be NULL. If not I'd rather use
asserts
but that's up to you.
}
// Standard access
T* operator->() { return m_ptr; }
T& operator*() { return *m_ptr; }
just a shame we can't overload operator .

Then we could make this a smart-reference (given that you don't want to
allow it to
be null or reassigned)
// Make pointee const if pointer is const
const T* operator->() const { return m_ptr; }
const T& operator*() const { return *m_ptr; }
I also might add methods to get the pointer other than operator-When
you have a function that wants a (const) T* pointer you don't want to
call myPtr->operator->() to get it (or &*myPtr)
private:
T * const m_ptr;

// Disabled copying
DeepPtr( const DeepPtr& );
unnecessary to disable assignment
DeepPtr& operator=( const DeepPtr& );
};

class A
{
DeepPtr<intm_pi1;
int *const m_pi2
public:
A( int* const pi1, int* const pi2 )
: m_pi1( pi1 ), m_pi2( pi2 )
{
*m_pi1 = 0xEATBEEF;
*m_pi2 = 0xEATBEEF;
// illegal: T is not a valid hex character,. You could assign to
0xEA7BEEF though.
}
The copy constructor and assignment operator are disable because they
would allow a backdoor to ignore constness (intentionally or not), and
as a result, this pointer proxy is not usable in standard containers
such as std::vector that require copy construction. It also means that
the example class A can't be copied either, but that may be acceptable
for your application.
The backdoor with copy-construction can be worked around by overloading
the copy-constructor to take a non-const reference (like auto_ptr
does). Then you can't duplicate a const "smart" pointer to remove its
constness.

Aug 31 '06 #19
Earl Purple wrote:
mlimber wrote:
template <class T>
class DeepPtr
{
public:
DeepPtr( T* const ptr )
: m_ptr( ptr )
{
if( !ptr )
{
throw MyException(); // or whatever
}

I'd prefer to allow such pointers to be NULL. If not I'd rather use
asserts
but that's up to you.
}
// Standard access
T* operator->() { return m_ptr; }
T& operator*() { return *m_ptr; }

just a shame we can't overload operator .

Then we could make this a smart-reference (given that you don't want to
allow it to
be null or reassigned)
// Make pointee const if pointer is const
const T* operator->() const { return m_ptr; }
const T& operator*() const { return *m_ptr; }

I also might add methods to get the pointer other than operator-When
you have a function that wants a (const) T* pointer you don't want to
call myPtr->operator->() to get it (or &*myPtr)
Sure. As per Alexandrescu's suggestion in _MC++D_, I have it as a
friendly free-standing function in my real code since it's not an
"official" part of the interface.
>
private:
T * const m_ptr;

// Disabled copying
DeepPtr( const DeepPtr& );

unnecessary to disable assignment
It is necessary. In my production code, I have a copy constructor that
takes non-const, and this line exists just to make explicit that I did
not want to allow copying from const. Omitting this line without that
other copy constructor, however, can lead to the un/intentional
ignoring of const that I mentioned:

void Foo( const DeepPtr<int>& pConst )
{
DeepPtr<intpNonConst( pConst );
*pConst = 42; // Error
*pNonConst = 42; // No error, but evil
}
DeepPtr& operator=( const DeepPtr& );
};

class A
{
DeepPtr<intm_pi1;
int *const m_pi2
public:
A( int* const pi1, int* const pi2 )
: m_pi1( pi1 ), m_pi2( pi2 )
{
*m_pi1 = 0xEATBEEF;
*m_pi2 = 0xEATBEEF;
// illegal: T is not a valid hex character,. You could assign to
0xEA7BEEF though.
Typing too quickly again. How about 0xBADBEEF?
>
}
The copy constructor and assignment operator are disable because they
would allow a backdoor to ignore constness (intentionally or not), and
as a result, this pointer proxy is not usable in standard containers
such as std::vector that require copy construction. It also means that
the example class A can't be copied either, but that may be acceptable
for your application.

The backdoor with copy-construction can be worked around by overloading
the copy-constructor to take a non-const reference (like auto_ptr
does). Then you can't duplicate a const "smart" pointer to remove its
constness.
Precisely what I do in my real code. I was simplifying here so as not
to obscure the main issue.

Cheers! --M

Aug 31 '06 #20
mlimber wrote:
Earl Purple wrote:
The backdoor with copy-construction can be worked around by overloading
the copy-constructor to take a non-const reference (like auto_ptr
does). Then you can't duplicate a const "smart" pointer to remove its
constness.

Precisely what I do in my real code. I was simplifying here so as not
to obscure the main issue.
However, your point is well-taken, and I probably shouldn't have
bothered simplifying that part.

Cheers! --M

Aug 31 '06 #21

mlimber wrote:
Earl Purple wrote:
unnecessary to disable assignment

It is necessary.
Yes it is necessary that assignment cannot take place but not necessary
to explicitly disable it as the preference of a const member will
automatically do that for you.

Sep 1 '06 #22

Ron Natalie wrote:
Noah Roberts wrote:

Yeah, that doesn't match the source code.

Once you get past a trivial declaration you're not going
to be able to linearly translate into something lexically
symentric. I say:
const char STAR foo
If I'm reading the code, but if I'm describing the
type I say
pointer to const char.

Trying to say something like

int *(*foo)(const char*, int(*)());

is just going to be gibberish read left to right.
Yeah, well do whatever you want. I find code more readable when it
reads clearly. I leave obscurity to those rare places where it's
needed. This also means I like sticking to "trivial" declarations
almost all the time.

Sep 1 '06 #23
Earl Purple wrote:
mlimber wrote:
Earl Purple wrote:
unnecessary to disable assignment
It is necessary.

Yes it is necessary that assignment cannot take place but not necessary
to explicitly disable it as the preference of a const member will
automatically do that for you.
Right you are. At least one of my compiler complains, however, if I
don't explicitly disable it.

Cheers! --M

Sep 1 '06 #24

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

19
2761
by: Christian Engström | last post by:
If you have a function that returns something by value, the gcc compiler (version 3.2.3 on Windows XP with MinGW) converts the returned value from the type you specify in the code, to the const...
19
6805
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:
2
3620
by: joe | last post by:
hi, after reading some articles and faq, i want to clarify myself what's correct(conform to standard) and what's not? or what should be correct but it isn't simply because compilers don't...
11
2345
by: Mantorok Redgormor | last post by:
Is const really constant? And on an OT note: how can I post with a modified e-mail address so I don't get so much spam?
11
2090
by: x-pander | last post by:
given the code: <file: c.c> typedef int quad_t; void w0(int *r, const quad_t *p) { *r = (*p); }
24
2293
by: kevin.hall | last post by:
Is char** (or char*) implicitly convertible to 'const char * const *'? I couldn't find anything about it in the standard. MSVS 8.0 allows this. I'm curious if I'll run into trouble with other...
18
1588
by: hzmonte | last post by:
typedef int t_compare_func(const void *, const void *); struct node *tree_search(struct node *root, const void *keyy, t_compare_func *comp) { struct node *cur_item; int result; if (root ==...
7
1857
by: Mark P | last post by:
The following compiles without error on four different platforms (Linux g++, Sun CC, HP aCC, Win Dev-C++) so I suspect it's ok, but I don't see why this isn't a const-related error. pB is a...
6
8287
by: Spoon | last post by:
Hello, I don't understand why gcc barks at me in this situation: $ cat foo.c extern void func(const int * const list, int nent); int main(void) { int *p;
0
7323
Oralloy
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,...
0
7380
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
1
7039
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...
0
7494
tracyyun
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...
1
5050
isladogs
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...
0
3192
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
3180
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
763
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
415
bsmnconsultancy
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...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.