473,513 Members | 2,559 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

compiler won't allow dimensioned array of Char* to be signed to another???

My compiler (m68k-gcc) does not allow this (simplified example; not my
real code) and I don't see why not:
{
char *arrayCharPtr1[] = {"a", "ab", NULL};
char *arrayCharPtr2[] = {"A", "AB", NULL};
char *arrayCharPtrVar[] =
((someBoolean) ? arrayCharPtr1 : arrayCharPtr2); // <-error here!
StrCopy(someString, arrayCharPtr[0]);
}

I have also tried "= &arrayCharPtr1[0]" which I assumed should work,
too; it doesn't.

What am I missing? How can this be done?
Nov 14 '05 #1
15 1711
Gregg Woodcock wrote:
My compiler (m68k-gcc) does not allow this (simplified example; not my
real code) and I don't see why not:
{
char *arrayCharPtr1[] = {"a", "ab", NULL};
char *arrayCharPtr2[] = {"A", "AB", NULL};
char *arrayCharPtrVar[] =
((someBoolean) ? arrayCharPtr1 : arrayCharPtr2); // <-error here!
StrCopy(someString, arrayCharPtr[0]);
}

I have also tried "= &arrayCharPtr1[0]" which I assumed should work,
too; it doesn't.
Declaration of an array of unknown size will only accept an aggregate
initializer (i.e. '{}'-enclosed initializer). The one you provided is not.
What am I missing? How can this be done?


What exactly are you trying to do?

--
Best regards,
Andrey Tarasevich
Nov 14 '05 #2
"Gregg Woodcock" <wo******@SonLightSoftware.com> wrote in message
news:86**************************@posting.google.c om...
My compiler (m68k-gcc) does not allow this (simplified example; not my
real code) and I don't see why not:
You could have explained what you intended in this code, I will try and guess
for now...
{
char *arrayCharPtr1[] = {"a", "ab", NULL};
char *arrayCharPtr2[] = {"A", "AB", NULL};
You should use const char * here because these arrays hold pointers to constant
string literals.
char *arrayCharPtrVar[] =
((someBoolean) ? arrayCharPtr1 : arrayCharPtr2); // <-error here!
Try this : char **arrayCharPtrVar = someBoolean ? arrayCharPtr1 : arrayCharPtr2;
Use const char **... if you followed my advice above.
StrCopy(someString, arrayCharPtr[0]);
StrCopy is not strcpy, what in hell can it do that strcpy can't ?
}

I have also tried "= &arrayCharPtr1[0]" which I assumed should work,
too; it doesn't.
The problem was with the type itself : you should declare a pointer, not an
agregate.
What am I missing? How can this be done?


Like I say.

--
Chqrlie.
PS: also your naming conventions are childish. CharPtr is useless, Var is
meaningless in variable names.
Use names like lower_strings[] and upper_strings[]...
Nov 14 '05 #3
Andrey Tarasevich <an**************@hotmail.com> wrote in message news:<10*************@news.supernews.com>...
Gregg Woodcock wrote:
My compiler (m68k-gcc) does not allow this (simplified example; not my
real code) and I don't see why not:
{
char *arrayCharPtr1[] = {"a", "ab", NULL};
char *arrayCharPtr2[] = {"A", "AB", NULL};
char *arrayCharPtrVar[] =
((someBoolean) ? arrayCharPtr1 : arrayCharPtr2); // <-error here!
StrCopy(someString, arrayCharPtr[0]);
}

I have also tried "= &arrayCharPtr1[0]" which I assumed should work,
too; it doesn't.


Declaration of an array of unknown size will only accept an aggregate
initializer (i.e. '{}'-enclosed initializer). The one you provided is not.
What am I missing? How can this be done?


What exactly are you trying to do?


You do a pretty good compiler immitation: perfectly accurate and
totally worthless.
I *KNOW* I cannot do what I want to do the way I am trying to do it
(the compiler is quite clear about that); That's why I gave the
complete context showing WHAT I want to do. I can hardly be more
clear.

I have to arrays of strings.
I want to assign one or the other array to a variable such that I can
index any string in the array with something like var[index].
It is very simple and I am quite sure not impossible...
Nov 14 '05 #4
wo******@SonLightSoftware.com (Gregg Woodcock) wrote:
My compiler (m68k-gcc) does not allow this (simplified example; not my
real code) and I don't see why not:
{
char *arrayCharPtr1[] = {"a", "ab", NULL};
char *arrayCharPtr2[] = {"A", "AB", NULL};
char *arrayCharPtrVar[] =
((someBoolean) ? arrayCharPtr1 : arrayCharPtr2); // <-error here!
StrCopy(someString, arrayCharPtr[0]);
}
I think you want:
char **arrayCharPtrVar =
((someBoolean) ? arrayCharPtr1 : arrayCharPtr2);

which will give you a pointer to the first element of either
array 1 or array 2.

If you have:
char *arrayCharPtrVar[]
then you are declaring another array (separate from the 2 existing
arrays). The best you can hope for here would be to have a copy
of one of your 2 arrays (giving you 3 arrays in total). If that's
what you want, then you can't do it with initializer syntax; you
will have to declare the array and then memcpy it from one of the
other two.

Incidentally, these should be: const char *arrayCharPtr1[] etc.
You can't modify a string literal, even though the language
allows you to assign them to a "char *" without warning.
So it is best to use "const" so that you will get a warning
if you try and modify one.

I have also tried "= &arrayCharPtr1[0]" which I assumed should work,
too; it doesn't.


'&a[0]' is identical to just 'a' , when used in an expression
(except for: sizeof(X) or &X or X++ etc.)
Nov 14 '05 #5
"Charlie Gordon" <ne**@chqrlie.org> wrote in message news:<co**********@reader1.imaginet.fr>...
"Gregg Woodcock" <wo******@SonLightSoftware.com> wrote in message
news:86**************************@posting.google.c om...
My compiler (m68k-gcc) does not allow this (simplified example; not my
real code) and I don't see why not:


You could have explained what you intended in this code, I will try and guess
for now...
{
char *arrayCharPtr1[] = {"a", "ab", NULL};
char *arrayCharPtr2[] = {"A", "AB", NULL};


You should use const char * here because
arrays hold pointers to constant string literals.


Normally I'd agree but I am programming for Palm (that explains the
StrCopy instead of strcopy which are essentially the same) and on the
Palm, declaring something as const causes the compiler to put it into
the local static code segment which, if it is not code segment #0 (in
my case it will not be) means it cannot be accessed by any other code
segment (which I require). This is certainly one good way to make it
unwritable!
char *arrayCharPtrVar[] =
((someBoolean) ? arrayCharPtr1 : arrayCharPtr2); // <-error here!


Try this : char **arrayCharPtrVar = someBoolean ? arrayCharPtr1 : arrayCharPtr2;
Use const char **... if you followed my advice above.


I should have mentioned I tried this too and it was not acceptible to
the compiler. However I just realized my mistake: I was compiling
pedantic and this was not an error but a WARNING! When I realized
this, I fixed it right away by casting like this:

char **arrayCharPtrVar =
((someBoolean) ? (char **)arrayCharPtr1 : (char **)arrayCharPtr2);

Thank you for your help!
Nov 14 '05 #6
Gregg Woodcock wrote:
Andrey Tarasevich <an**************@hotmail.com> wrote in message
Gregg Woodcock wrote:

My compiler (m68k-gcc) does not allow this (simplified example;
not my real code) and I don't see why not:
{
char *arrayCharPtr1[] = {"a", "ab", NULL};
char *arrayCharPtr2[] = {"A", "AB", NULL};
char *arrayCharPtrVar[] =
((someBoolean) ? arrayCharPtr1 : arrayCharPtr2); // <-error here!
StrCopy(someString, arrayCharPtr[0]);
}

I have also tried "= &arrayCharPtr1[0]" which I assumed should
work, too; it doesn't.


Declaration of an array of unknown size will only accept an
aggregate initializer (i.e. '{}'-enclosed initializer). The one
you provided is not.
> What am I missing? How can this be done?


What exactly are you trying to do?


You do a pretty good compiler immitation: perfectly accurate and
totally worthless.
I *KNOW* I cannot do what I want to do the way I am trying to do it
(the compiler is quite clear about that); That's why I gave the
complete context showing WHAT I want to do. I can hardly be more
clear.

I have to arrays of strings.
I want to assign one or the other array to a variable such that I can
index any string in the array with something like var[index].
It is very simple and I am quite sure not impossible...


You have successfully formed your arrays of pointers to strings, so
your only purpose is to select one for future use. Think about how
those arrays are represented: they are passed as a pointer to the
first element, i.e. as the address of a location holding a char *.

Your final result needs to be of this type, not of an array of
pointers. So declare it as such:

char *arrayCharPtrVar;

and follow up with code to initialize it.

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!

Nov 14 '05 #7
On 1 Dec 2004 19:32:13 -0800
wo******@SonLightSoftware.com (Gregg Woodcock) wrote:
"Charlie Gordon" <ne**@chqrlie.org> wrote in message
news:<co**********@reader1.imaginet.fr>...
"Gregg Woodcock" <wo******@SonLightSoftware.com> wrote in message
news:86**************************@posting.google.c om...
My compiler (m68k-gcc) does not allow this (simplified example;
not my real code) and I don't see why not:


You could have explained what you intended in this code, I will try
and guess for now...
{
char *arrayCharPtr1[] = {"a", "ab", NULL};
char *arrayCharPtr2[] = {"A", "AB", NULL};


You should use const char * here because
arrays hold pointers to constant string literals.


Normally I'd agree but I am programming for Palm (that explains the
StrCopy instead of strcopy which are essentially the same) and on the
Palm, declaring something as const causes the compiler to put it into
the local static code segment which, if it is not code segment #0 (in
my case it will not be) means it cannot be accessed by any other code
segment (which I require). This is certainly one good way to make it
unwritable!


As long as you are only accessing it for reading!
char *arrayCharPtrVar[] =
((someBoolean) ? arrayCharPtr1 : arrayCharPtr2); // <-error
here!


Try this : char **arrayCharPtrVar = someBoolean ? arrayCharPtr1 :
arrayCharPtr2; Use const char **... if you followed my advice above.


I should have mentioned I tried this too and it was not acceptible to
the compiler. However I just realized my mistake: I was compiling
pedantic and this was not an error but a WARNING! When I realized
this, I fixed it right away by casting like this:

char **arrayCharPtrVar =
((someBoolean) ? (char **)arrayCharPtr1 : (char **)arrayCharPtr2);


The warning doesn't meen you need a cast, it meens the variable is of
the wrong type somewhere, either that or the compiler is broken or you
are not doine what you show.

markg@brenda ~ $ cat t.c
#include <stdlib.h>

int main(int argc, char *argv[])
{
char *arrayCharPtr1[] = {"a", "ab", NULL};
char *arrayCharPtr2[] = {"A", "AB", NULL};
int someBoolean = 0;
char **arrayCharVarPtr =
(someBoolean) ? arrayCharPtr1 : arrayCharPtr2;
return 0;
}
markg@brenda ~ $ gcc t.c -ansi -pedantic -Wall -O
t.c: In function `main':
t.c:8: warning: unused variable `arrayCharVarPtr'
markg@brenda ~ $

Not that gcc defines what is acceptable, but it is pretty good about
complaining about producing required diagnostics for incompatible
pointer types.

I *strongly* suggest you try running the above code as is through your
compiler with the pedantic switch and if it compiles OK go back to your
code and see what you have done differently.
--
Flash Gordon
Living in interesting times.
Although my email address says spam, it is real and I read it.
Nov 14 '05 #8
wo******@SonLightSoftware.com (Gregg Woodcock) wrote:
char *arrayCharPtr1[] = {"a", "ab", NULL};
char *arrayCharPtr2[] = {"A", "AB", NULL};
You should use const char * here because
arrays hold pointers to constant string literals.


Normally I'd agree but I am programming for Palm and on the
Palm, declaring something as const causes the compiler to put it into
the local static code segment which, if it is not code segment #0 (in
my case it will not be) means it cannot be accessed by any other code
segment (which I require). This is certainly one good way to make it
unwritable!


The 'const' refers to the chars, not to the array of them.
The array will be in your modifiable data space, regardless
of whether the chars are const or not.
Where the compiler places string literals is also independent
of how you refer to them later. You can control this with a
linker switch, if at all.
I expect you will find that changing "char *" to "const char *"
won't affect where in memory anything gets put (try it and see).
char *arrayCharPtrVar[] =
((someBoolean) ? arrayCharPtr1 : arrayCharPtr2); // <-error here!


I should have mentioned I tried this too and it was not acceptible to
the compiler. However I just realized my mistake: I was compiling
pedantic and this was not an error but a WARNING! When I realized
this, I fixed it right away by casting like this:

char **arrayCharPtrVar =
((someBoolean) ? (char **)arrayCharPtr1 : (char **)arrayCharPtr2);


Can you say what the error message was? The type of "arrayCharPtr1"
in an expression is already "char **", so either your compiler
is awful, you didn't post the exact code, or there is some other
condition (possibly related to the code segments you mentioned)
that you are shutting up by doing the cast but would cause a
runtime error.
Nov 14 '05 #9
"CBFalconer" <cb********@yahoo.com> wrote in message
news:41***************@yahoo.com...
Gregg Woodcock wrote:

I have to arrays of strings.
I want to assign one or the other array to a variable such that I can
index any string in the array with something like var[index].
It is very simple and I am quite sure not impossible...


You have successfully formed your arrays of pointers to strings, so
your only purpose is to select one for future use. Think about how
those arrays are represented: they are passed as a pointer to the
first element, i.e. as the address of a location holding a char *.

Your final result needs to be of this type, not of an array of
pointers. So declare it as such:

char *arrayCharPtrVar;

and follow up with code to initialize it.


nonsense!

char **arrayCharPtrVar;

--
Chqrlie.
Nov 14 '05 #10
Charlie Gordon wrote:
"CBFalconer" <cb********@yahoo.com> wrote in message
Gregg Woodcock wrote:

I have to arrays of strings.
I want to assign one or the other array to a variable such that I can
index any string in the array with something like var[index].
It is very simple and I am quite sure not impossible...


You have successfully formed your arrays of pointers to strings, so
your only purpose is to select one for future use. Think about how
those arrays are represented: they are passed as a pointer to the
first element, i.e. as the address of a location holding a char *.

Your final result needs to be of this type, not of an array of
pointers. So declare it as such:

char *arrayCharPtrVar;

and follow up with code to initialize it.


nonsense!

char **arrayCharPtrVar;


Why do you want a pointer to (a pointer to a char)?

If it is not clear draw yourself some box diagrams, showing what
points where. The only initialized elements are the original
arrays of pointers.

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!
Nov 14 '05 #11
"CBFalconer" <cb********@yahoo.com> wrote in message
news:41***************@yahoo.com...
Charlie Gordon wrote:
"CBFalconer" <cb********@yahoo.com> wrote in message [snip]
You have successfully formed your arrays of pointers to strings, so
your only purpose is to select one for future use. Think about how
those arrays are represented: they are passed as a pointer to the
first element, i.e. as the address of a location holding a char *.

Your final result needs to be of this type, not of an array of
pointers. So declare it as such:

char *arrayCharPtrVar;

and follow up with code to initialize it.


nonsense!

char **arrayCharPtrVar;


Why do you want a pointer to (a pointer to a char)?


Because "the address of a location holding a char *" has type char **, and
the "final result needs to be of this type".

Alex
Nov 14 '05 #12


Gregg Woodcock wrote:
My compiler (m68k-gcc) does not allow this (simplified example; not my
real code) and I don't see why not:
{
char *arrayCharPtr1[] = {"a", "ab", NULL};
char *arrayCharPtr2[] = {"A", "AB", NULL};
char *arrayCharPtrVar[] =
((someBoolean) ? arrayCharPtr1 : arrayCharPtr2); // <-error here!
StrCopy(someString, arrayCharPtr[0]);
}

I have also tried "= &arrayCharPtr1[0]" which I assumed should work,
too; it doesn't.

What am I missing? How can this be done?


In the initialization of arrayCharPtrVar, you are not providing values
appropriate for the entity being initialized.

You can use function memcpy.

#include <stdio.h>
#include <string.h>

int main(void)
{
char *arrayCharPtr1[] = {"a", "ab", NULL};
char *arrayCharPtr2[] = {"A", "AB", NULL};
char *arrayCharPtrVar[3];
int b , i;

for(b = 0; b < 2; b++)
{
memcpy(arrayCharPtrVar,b?arrayCharPtr2:arrayCharPt r1,
sizeof arrayCharPtrVar);
printf("b = %d\n",b);
for(i = 0; i < 3; i++)
if(arrayCharPtrVar[i])
printf("arrayCharPtrVar[%d] = \"%s\"\n",
i,arrayCharPtrVar[i]);
putchar('\n');
}
return 0;
}

--
Al Bowers
Tampa, Fl USA
mailto: xa******@myrapidsys.com (remove the x to send email)
http://www.geocities.com/abowers822/

Nov 14 '05 #13
Alex Fraser wrote:
"CBFalconer" <cb********@yahoo.com> wrote in message
Charlie Gordon wrote:
"CBFalconer" <cb********@yahoo.com> wrote in message [snip] You have successfully formed your arrays of pointers to strings, so
your only purpose is to select one for future use. Think about how
those arrays are represented: they are passed as a pointer to the
first element, i.e. as the address of a location holding a char *.

Your final result needs to be of this type, not of an array of
pointers. So declare it as such:

char *arrayCharPtrVar;

and follow up with code to initialize it.

nonsense!

char **arrayCharPtrVar;


Why do you want a pointer to (a pointer to a char)?


Because "the address of a location holding a char *" has type char **,
and the "final result needs to be of this type".


No you don't. If you have

int x;

and you want to place a value into that location, you simply write
"x = value;". There is no need whatsoever to take the address of
x. Same thing.

char *p;

p = somepointer;

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!
Nov 14 '05 #14
"CBFalconer" <cb********@yahoo.com> wrote in message
news:41***************@yahoo.com...
Alex Fraser wrote:
"CBFalconer" <cb********@yahoo.com> wrote in message
Charlie Gordon wrote:
"CBFalconer" <cb********@yahoo.com> wrote in message

[snip]
> You have successfully formed your arrays of pointers to strings, so
> your only purpose is to select one for future use. Think about how
> those arrays are represented: they are passed as a pointer to the
> first element, i.e. as the address of a location holding a char *.
>
> Your final result needs to be of this type, not of an array of
> pointers. So declare it as such:
>
> char *arrayCharPtrVar;
>
> and follow up with code to initialize it.

nonsense!

char **arrayCharPtrVar;

Why do you want a pointer to (a pointer to a char)?


Because "the address of a location holding a char *" has type char **,
and the "final result needs to be of this type".


No you don't. [...]


Sorry, but you do. The words in your first post were correct, but the code
was not.

char *array1[] = {"one", "two", 0};
char *array2[] = {"three", "four", 0};
char **p = condition() ? array1 : array2;

Alex
Nov 14 '05 #15
CBFalconer wrote:
Alex Fraser wrote:
"CBFalconer" <cb********@yahoo.com> wrote in message
Charlie Gordon wrote:

"CBFalconer" <cb********@yahoo.com> wrote in message


[snip]
>You have successfully formed your arrays of pointers to strings, so
>your only purpose is to select one for future use. Think about how
>those arrays are represented: they are passed as a pointer to the
>first element, i.e. as the address of a location holding a char *.
>
>Your final result needs to be of this type, not of an array of
>pointers. So declare it as such:
>
>char *arrayCharPtrVar;
>
>and follow up with code to initialize it.

nonsense!

char **arrayCharPtrVar;

Why do you want a pointer to (a pointer to a char)?


Because "the address of a location holding a char *" has type char **,
and the "final result needs to be of this type".

No you don't. If you have

int x;

and you want to place a value into that location, you simply write
"x = value;". There is no need whatsoever to take the address of
x. Same thing.

char *p;

p = somepointer;


One of us is missing the point(er). :-)

Given an array..

char arr[] = "Hello World";

...we all know that expressing arr 'decays' to a pointer to the first
element, the 'H'. Knowing this we can do..

char *ptr = arr;

... and now we can express arr[6] or ptr[6] yielding 'W' and nobody
knows the difference.

Paraphrasing the OP, we have two given definitions..

char *apc1[] = {"a", "ab", 0};
char *apc2[] = {"A", "AB", 0};

Both of these define an array [3] of pointers to char. Expressing
the array yields a pointer to its first element, a pointer to char. So..

char **papc = apc1;

...will allow apc1 and papc to behave identically in array notation.
The expression (apc1[1] == papc[1]) is true. Depending on (cond) to
choose papc..

char **papc;
papc = (cond) ? apc1 : apc2;

...is the way it's done.

--
Joe Wright mailto:jo********@comcast.net
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---
Nov 14 '05 #16

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

Similar topics

9
3246
by: w3r3w0lf | last post by:
hello! I have a following situation: I have a byte array where at a certain location are stored 4 bytes, and these should be "put" into long variable (or any other 4 byte one). ie: byte...
13
1318
by: junky_fellow | last post by:
N869, Page 47, "Except when it is the operand of the sizeof operator or the unary & operator, or is a string literal used to initialize an array, an expression that has type ''array of type'' is...
16
10082
by: Dave | last post by:
Hi all, I have a 4 byte char array with the binary data for two 16-bit signed integers in it like this: Index 3 2 1 0 Data Bh Bl Ah Al Where Bh is the high byte of signed 16-bit...
15
2325
by: Claudio Grondi | last post by:
Let's consider a test source code given at the very end of this posting. The question is if Python allows somehow access to the bytes of the representation of a long integer or integer in...
5
2123
by: Richard Lewis Haggard | last post by:
I am trying to create multi-dimensioned arrays in conventional ASP pages and pass these arrays as arguments to functions that are in a C# interop assembly. ASP complains because it doesn't...
8
1989
by: Charles Sullivan | last post by:
I have a program written in C under Linux (gcc) which a user has ported to run under AT&T SysV R4. He sent me a copy of his makelog which displays a large number of compiler warnings similar to...
17
1503
by: mdh | last post by:
I am working on 5.11 ( once again). So, just stepping through code in the debugger, and get this...and cannot proceed. Have posted to the Xcode forum, but my guess is the real gurus are here in...
16
1374
by: Vols | last post by:
char s = "1234567"; when we use C compiler (gcc), it works fine. An error is reported if using C++ compiler (g++). any story for this one? Vol
37
1955
by: Richard Heathfield | last post by:
candide said: They aren't. An array is an array. An address is a pointer value. These are not the same thing. If you mean that &array and &array are the same, they aren't. They have different...
0
7160
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...
0
7384
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,...
1
7099
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
7525
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...
0
5685
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
3222
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
1594
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 ...
1
799
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
456
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.