473,883 Members | 1,674 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

why still use C?

no this is no trollposting and please don't get it wrong but iam very
curious why people still use C instead of other languages especially C++.

i heard people say C++ is slower than C but i can't believe that. in pieces
of the application where speed really matters you can still use "normal"
functions or even static methods which is basically the same.

in C there arent the simplest things present like constants, each struct and
enum have to be prefixed with "struct" and "enum". iam sure there is much
more.

i don't get it why people program in C and faking OOP features(functi on
pointers in structs..) instead of using C++. are they simply masochists or
is there a logical reason?

i feel C has to benefit against C++.

--
cody

[Freeware, Games and Humor]
www.deutronium.de.vu || www.deutronium.tk
--
comp.lang.c.mod erated - moderation address: cl**@plethora.n et
Nov 13 '05
687 23872
Mark McIntyre wrote:
[...] I feel my code looks prettier with malloc() casts.
what, you think this looks prettier
foo = (struct myweirdstruct*) malloc( sizeof (myweirdstruct) );
than
foo = malloc (sizeof *foo);
???????


Well yes, although I feel

foo = (struct myweirdstruct *)malloc(sizeof (struct myweirdstruct)) ;

looks prettier still.
2. Casting malloc's return value may hide the (admittedly simple to fix)
error of not providing a proper prototype for malloc.


If this is the case, I seriously doubt the quality of the compiler:

Many compilers only *warn* about implicit function declarations on
their default warning level. My "many" I mean "pretty much all the
popular ones"


Pretty much all the popular ones also have an option to turn warnings
into errors, don't they?
The standard doesn't require the compiler to issue a warning of course
(never does), but I think, the year being AD2003 and all, that a
good-quality compiler should issue a warning whether the (char *) cast
is there or not.

A warning is typically not a compilation halting operation. Thus
during an automated build, this error might go unnoticed.


I either use -Werror with gcc or colormake, a few times a week.
Having one's C program compilable by a C++-compiler also helps, since
this can sometimes flag potential problems in the C code that are not
noticed by a C compiler.

<snip enum example claiming ti support this>


I think 'claiming to support' is a bit dismissive? I think my example is
excellent, actually! :-)
This is a perfectly legal C program as far as I can tell, and it's
illegal in C++ due to the attempt to implicitly casting 1 to EType. but in C, this is not an error.
That's my point. I think it should be an error. If I write a line like
f(1) where the parameter ought to be an enum I want to know. I have to
resort to C++ for that and the price-to-pay is casting malloc results.
I think C++ is right to flag this as erroneous, and require a cast.

not in C, its not. Remember that enums are not a new type in C,
they're ints. So you are inserting another useless cast, obfuscating
your code slightly for no benefit.


The benefit, I hesitate to repeat, is the ability to compile my C
program with a C++ compiler as well.

Best regards,

Sidney Cadot

Nov 13 '05 #291
"P.J. Plauger" <pj*@dinkumware .com> wrote:
"Irrwahn Grausewitz" <ir*******@free net.de> wrote in message
news:v1******* *************** **********@4ax. com...
<snip>
The special cases are the reason why I said "most probably" and not
"certainly" . However, low-level code is unlikely to be pure portable
ISO-C anyway.


Gee, I just counted a couple of hundred casts in our C code, which runs
on a dozen or more platforms. I'd estimate that only a few per cent of
them could safely be removed, including the malloc ones.


I admit that, coming from another programming domain, I made a frivolous
claim, but it's good to see that you[...] agree that
casts can be dangerous, so I only write them when I think they serve
a good purpose. In the cases I just counted, almost all are needed to
*ensure* portability. Go figure.
<snip>I'd like to agree, but we also add casts to our code to silence compiler
warnings that are silly. (Why do some compilers complain about -x, where
x is unsigned, but say nothing about 0-x?) Our customers do *not* want
warning messages from our code, no matter how much we assure them that
we know what we're doing.
Well, I consider silly compiler warnings to be an exceptional thing.

<snip>
>I think that is a mistake, and I am not going to drop casts that are not
>needed just because the standard allows me to.


If you think that C99 6.3.2.3 is a mistake, you should submit a DR or a
proposal to the standards comittee. ;-)


You may not like it, but it *was* intentional.


Huh?!? Who do you mean by 'you', Sidney or me?

<snip>
If one prefers C++ over C for certain reasons, why not write C++ in the
first place, instead of breeding a chimera that's neither idiomatic C
nor idiomatic C++.


Because it's idiomatic common subset, and superior for both purposes?


The intersection of C and C++ excludes idioms of both languages. That's
not superior, it's a limitation.

<snip>
>... I am, however, advocating writing code that
>complies with the intersection of C and C++, and works as intended. You
>are coming perilously close to putting up a strawman here.


Am I? Then please tell me where the common subset of C and C++ is
defined, so I have something to make my code comply to, just in case I
want to code the same way you do; is it different for C89 compared to
C99? Please give a reference. Now who was how close to putting up a
strawman? ;-P


You are. You don't want to code in the common subset, don't.


You, like Sidney, seem to have missed my point. Don't mind.
If you want
to learn how to write code that works the same way when compiled as C89,
C99, and C++, it ain't that hard.
Well, for non-experts like me it /is/ hard, to some extent.
I feel no obligation to help educate
you, however.


Thanks for offering no help, I'll stick to just writing C as good as I
can. ;-)

Regards
--
Irrwahn
(ir*******@free net.de)
Nov 13 '05 #292
Irrwahn Grausewitz wrote:
[snippedysnip]
No, that's not what I said. My opinion is this: A decent C89 compiler
should be able to warn on non-prototyped functions being used, even
though C89 allows it.
<snip>
... You misunderstood my definition. All compilers I've used are able to
warn on non-prototyped function usage.


I was off-track then.


Ok, that's sorted out.
<snip>
Here's another one:
A perfectely valid Spanish sentence can also be a perfectly valid
Portugese sentence, but with a different meaning. The fact that both
are somewhat close related languages doens't make them compatible.


...Now suppose you have a machine that understands Spanish, and a
machine that understands Portugese. Both machines warn on incorrect
syntax and grammer in their respectively understood languages. Let's
also assume (to make the metaphor a bit more realistic) that Portugese
descends from Spanish, adding a few grammatic constructs, and that most
Spanish sentences (except from contrived examples) are also correct
Portugese (though not the other way round). Finally, let's assume
Portugese is a lot stricter concerning grammatical constructs; some
sentences that are legal Spanish but often lead to problems are
incorrect in Portugese.

Now we have a valid metaphor. I'm advocating that, if you try to write
problem-free Spanish, using both machines instead of just the Spanish
one can be of help.


But doing so you would have to avoid some common spanish idioms, which
will likely result in constructs that sound strange to native Spanish
speaking persons - the human readers of your code, to stress the
metaphor even more.


In practice, it's really almost exclusively the casting of malloc()
results you need to take care of, and avoiding a couple of C++-keywords,
to get C++-compliant code. The numbers of idioms to avoid is therefore
rather limited. And I have, in the past, reapt real benefits from
C++-compiling C-programs.

I would recommend to anybody to give this a shot... Cast the mallocs on
a smallish (1000--2000 line) C-program, and turn loose a C++-compiler on
it with maximum warning level. You may be surprised at what you get.
<snip>
I would kindly refer you to my reply to Cody's questions of 5 october. I
prefer C for many reasons, but I also recognise that C++ aims to fix
some problems in C. I'm aiming for the 'best of both worlds' approach.

But why not use tools that are specially designed for testing C code?
What if the common subset of C and C++ becomes smaller after some more
revisions of the standards? The 'best of both worlds' may turn into the
'worst of both worlds' some day...


One has to be practical in these matters. When divergence happens to the
point where taking care of C++ compliance of one's C code is no longer
possible, I will abandon this. Today it works for me.
<snip>
It's not wrong from the C standard's point-of-view, but then I feel the
C standard is wrong in this respect. The rationale for allowing implicit
int-to-enum conversion at the time was undoubtedly the desire to not
break existing code, but as far as I am concerned the time has come to
leave this behind for new code.
I agree that the "oh no, don't break existing code" concept breeds the
danger of stagnation. And the "lack" of typesafety in C is, has been
and will probably always be a debatable point. I feel comfortable with
it as it is, otherwise I'd probably use some other language. Though
one has to watch ones step very carefully.


Sure. I would love to have my steps monitored closely by the compiler
though.
<snip: language intersections>

Hm, seems to me you didn't get my point:
It's not the concept that's hard to understand, it's just that the
mentioned intersection isn't standardized. I don't like the idea
of having to change my coding style whenever each of the standards
changes.


Ok, that's a valid point. For now, it can be done; in 5 years, who
knows. Of course C and C++ are not (yet) developing independently;
there's cross-pollination and that's bound to keep 'em together for most
basic things in the years to come. My guess is, at the time when they
diverge, C will have a standard without implicit cast to/from void*.
Then again I could be wrong.
In fact, as long as I can't claim to have "incorporat ed" at

least 80% of _one_ standard, I won't bother to even try to define the
common subset of two (or three) standards. Maybe I'm just dumb. %O
Well, we could form a committee to exactely define the common subset
of both languages, but, er, well, what shall I say? :-)


Good plan. A good starting point would be the C++ standard without the
exceptions, templates, and STL parts.

(ducks)
Regards,

Sidney

Nov 13 '05 #293
Mark McIntyre wrote:
On Sat, 18 Oct 2003 23:04:51 +0200, in comp.lang.c , Sidney Cadot
<si****@jigsaw. nl> wrote:

foop barp;
barp = (foop)malloc(co unt * sizeof *barp);

its not supposed to /prevent/ you from writing it, its supposed to
prevent you from /needing/ to write it.


Well, I need it to compile my program with a C++ compiler, so that
doesn't help.
By using CBF's method, you can change the type of barp, and ripple
that through all your code, by changing only one line of code, instead
of the 1000s of places you've malloced barps. Sure, you still have to
chagne places that you *use* a barp, but you've still reduced
maintenance costs sharply.
Let's not exagerrate the maintenance cost of such an operation. It's not
like I will have to look for a piece of hay in a massive stack of
needles, or anything... The compiler is my friend, also for this type of
renaming.
What do you thin that casting malloc does? How does it improve either
your code quality or readability? Its a serious question.


As I explained in a post of 20 minutes ago, I view a cast as a means of
setting a misguided compiler on the right course, with regard to the
type of an object a pointer points to.

Best regards,

Sidney Cadot


Nov 13 '05 #294
Sidney Cadot <si****@jigsaw. nl> wrote:
Mark McIntyre wrote:

[...]
what, you think this looks prettier
foo = (struct myweirdstruct*) malloc( sizeof (myweirdstruct) );
than
foo = malloc (sizeof *foo);
???????


Well yes, although I feel

foo = (struct myweirdstruct *)malloc(sizeof (struct myweirdstruct)) ;

looks prettier still.


Well, it's correct, as opposed to Marks first alternative, but anyway:

Beauty is in the eye of the beholder. :)

Regards
--
Irrwahn
(ir*******@free net.de)
Nov 13 '05 #295
Sidney Cadot <si****@jigsaw. nl> wrote:
Irrwahn Grausewitz wrote: <much snippage>
Now we have a valid metaphor. I'm advocating that, if you try to write
problem-free Spanish, using both machines instead of just the Spanish
one can be of help.


But doing so you would have to avoid some common spanish idioms, which
will likely result in constructs that sound strange to native Spanish
speaking persons - the human readers of your code, to stress the
metaphor even more.


In practice, it's really almost exclusively the casting of malloc()
results you need to take care of, and avoiding a couple of C++-keywords,
to get C++-compliant code. The numbers of idioms to avoid is therefore
rather limited. And I have, in the past, reapt real benefits from
C++-compiling C-programs.


Well, I'm still not sure about that matter, but anyway: if it suits your
needs, do it, I most probably won't, but ...
I would recommend to anybody to give this a shot... Cast the mallocs on
a smallish (1000--2000 line) C-program, and turn loose a C++-compiler on
it with maximum warning level. You may be surprised at what you get.
.... maybe I'll give it a try occasionally.

<snip>
I agree that the "oh no, don't break existing code" concept breeds the
danger of stagnation. And the "lack" of typesafety in C is, has been
and will probably always be a debatable point. I feel comfortable with
it as it is, otherwise I'd probably use some other language. Though
one has to watch ones step very carefully.


Sure. I would love to have my steps monitored closely by the compiler
though.


Well, if it's for me, not too close, please ...

<snip: language intersections>
Ok, that's a valid point. For now, it can be done; in 5 years, who
knows. Of course C and C++ are not (yet) developing independently;
there's cross-pollination and that's bound to keep 'em together for most
basic things in the years to come. My guess is, at the time when they
diverge, C will have a standard without implicit cast to/from void*.
Then again I could be wrong.


Fair enough.
In fact, as long as I can't claim to have "incorporat ed" at
least 80% of _one_ standard, I won't bother to even try to define the
common subset of two (or three) standards. Maybe I'm just dumb. %O
Well, we could form a committee to exactely define the common subset
of both languages, but, er, well, what shall I say? :-)


Good plan. A good starting point would be the C++ standard without the
exceptions, templates, and STL parts.

(ducks)


Hehehe :D

Regards,
--
Irrwahn
(ir*******@free net.de)
Nov 13 '05 #296
"Irrwahn Grausewitz" <ir*******@free net.de> wrote in message
news:s9******** *************** *********@4ax.c om...
I'd like to agree, but we also add casts to our code to silence compiler
warnings that are silly. (Why do some compilers complain about -x, where
x is unsigned, but say nothing about 0-x?) Our customers do *not* want
warning messages from our code, no matter how much we assure them that
we know what we're doing.
Well, I consider silly compiler warnings to be an exceptional thing.


If only that were true. When you ship a source package designed to compile
with many different compilers, you'd be surprised what the union of all
silly compiler warnings can add up to.
<snip>
>I think that is a mistake, and I am not going to drop casts that are not
>needed just because the standard allows me to.

If you think that C99 6.3.2.3 is a mistake, you should submit a DR or a
proposal to the standards comittee. ;-)
You may not like it, but it *was* intentional.


Huh?!? Who do you mean by 'you', Sidney or me?


Sorry, I was indeed pointing one back. Should have made that clearer.
If one prefers C++ over C for certain reasons, why not write C++ in the
first place, instead of breeding a chimera that's neither idiomatic C
nor idiomatic C++.


Because it's idiomatic common subset, and superior for both purposes?


The intersection of C and C++ excludes idioms of both languages. That's
not superior, it's a limitation.


Not necessarily. Programming languages must choose when to permit shorthand
and when to demand redundancy -- primarily in the interest of maximizing
readability and maintainability (IMO). I've found the common subset to be
a pretty good dialect in that regard.
<snip>
>... I am, however, advocating writing code that
>complies with the intersection of C and C++, and works as intended. You
>are coming perilously close to putting up a strawman here.

Am I? Then please tell me where the common subset of C and C++ is
defined, so I have something to make my code comply to, just in case I
want to code the same way you do; is it different for C89 compared to
C99? Please give a reference. Now who was how close to putting up a
strawman? ;-P


You are. You don't want to code in the common subset, don't.


You, like Sidney, seem to have missed my point. Don't mind.


I didn't miss your point, just chose not to address it. Once again, I
could have been clearer.
If you want
to learn how to write code that works the same way when compiled as C89,
C99, and C++, it ain't that hard.


Well, for non-experts like me it /is/ hard, to some extent.


In that case, dig up Tom Plum's book on C programming guidelines. IIRC,
it does indeed describe how to write "safer C" in the common subset --
if only as a stepping stone when migrating to C++.
I feel no obligation to help educate
you, however.


Thanks for offering no help, I'll stick to just writing C as good as I
can. ;-)


As I said before, that's fine with me.

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com
Nov 13 '05 #297
Mark McIntyre wrote:
The function of a cast is to silence a compiler warning.


Not so. The function of a cast is to convert "the value of the expression to
the named type." (Of course, it's the programmer's job to ensure that the
conversion is meaningful.)

--
Richard Heathfield : bi****@eton.pow ernet.co.uk
"Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
K&R answers, C books, etc: http://users.powernet.co.uk/eton
Nov 13 '05 #298
Fergus Henderson <fj*@cs.mu.oz.a u> wrote:
Jerry Feldman <ga********@blu .org> writes:
Keith Thompson <ks*@cts.com> wrote:
C++ has never been a strict superset of any version of C. C++ has
several keywords that are not reserved in C; that alone makes prevents
it from being a superset.


I agree that "C++ has never been a strict superset of any version of C",
but I disagree with your logic. A superset can define new keywords (and
comment operators).


A strict superset can't, if those keywords have names which are not
already reserved for use by the implementation, because adding new
keywords will invalidate existing C programs that happen to use those
keywords as identifiers.

Adding new comment operators can also change the meaning of existing code.
Consider the following program:

int main() {
printf(1//**/2
? "fail\n" : "pass\n");
return 0;
}

On a conforming C89 implementation, this will print "pass",
but on a C++ or C99 implementation, it will print "fail".

<snip>

Congratulations , you just "proved" that C99 isn't a superset[1] of C89.
;-P

[1] According to your definition of "superset".

Regards
--
Irrwahn
(ir*******@free net.de)
--
comp.lang.c.mod erated - moderation address: cl**@plethora.n et
Nov 13 '05 #299
On 13 Oct 2003 18:49:35 GMT in comp.std.c, th*@cs.ucr.edu wrote:
In comp.std.c Douglas A. Gwyn <DA****@null.ne t> wrote:
+ th*@cs.ucr.edu wrote:
+> Compiling C programs with a C++ compiler has the benefit that C++
+> compilers are required to perform intermodule type checking. But I'm
+> told that this intermodule type checking is a curse when one tries to
+> use precompiled libraries that have been compiled on different C++
+> compilers, since that checking is usually based on name-mangling and
+> there is no name-mangling standard. (Perhaps others have more
+> experience with that issue.)
+
+ On essentially any platform there is a unique standard API
+ for C linkage. And it is easy to get that linkage from C++
+ by using "extern C". Therefore, libraries written in C are
+ readily used from both C and C++ applications. Libraries
+ that rely on C++-specific features (e.g. classes) are not
+ readily used from C applications.

Is it feasible to interpose a proxy library whose headers are
conforming C code that's compiled with a C++ compiler and that calls
functions from the C++ library?


What conclusions could be drawn from the "extern C" linkage?

Thanks. Take care, Brian Inglis Calgary, Alberta, Canada
--
Br**********@CS i.com (Brian dot Inglis at SystematicSw dot ab dot ca)
fake address use address above to reply
--
comp.lang.c.mod erated - moderation address: cl**@plethora.n et
Nov 13 '05 #300

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

Similar topics

3
11266
by: William C. White | last post by:
Does anyone know of a way to use PHP /w Authorize.net AIM without using cURL? Our website is hosted on a shared drive and the webhost company doesn't installed additional software (such as cURL) on the server because of that. Our site will have an SSL certificate next week, so I would like to use AIM instead of SIM, however, I don't know how to send data via POST over https and recieve data from the Authorize.net server over an https...
2
5865
by: Albert Ahtenberg | last post by:
Hello, I don't know if it is only me but I was sure that header("Location:url") redirects the browser instantly to URL, or at least stops the execution of the code. But appearantely it continues to execute the code until the browser send his reply to the header instruction. So an exit(); after each redirection won't hurt at all
3
23053
by: James | last post by:
Hi, I have a form with 2 fields. 'A' 'B' The user completes one of the fields and the form is submitted. On the results page I want to run a query, but this will change subject to which field is completed.
0
8508
by: Ollivier Robert | last post by:
Hello, I'm trying to link PHP with Oracle 9.2.0/OCI8 with gcc 3.2.3 on a Solaris9 system. The link succeeds but everytime I try to run php, I get a SEGV from inside the libcnltsh.so library. 354 roberto@ausone:Build/php-4.3.2> ldd /opt/php4/bin/php libsablot.so.0 => /usr/local/lib/libsablot.so.0 libstdc++.so.5 => /usr/local/lib/libstdc++.so.5 libm.so.1 => /usr/lib/libm.so.1
1
8621
by: Richard Galli | last post by:
I want viewers to compare state laws on a single subject. Imagine a three-column table with a drop-down box on the top. A viewer selects a state from the list, and that state's text fills the column below. The viewer can select states from the drop down lists above the other two columns as well. If the viewer selects only one, only one column fills. If the viewer selects two states, two columns fill. Etc. I could, if appropriate, have...
4
18317
by: Albert Ahtenberg | last post by:
Hello, I have two questions. 1. When the user presses the back button and returns to a form he filled the form is reseted. How do I leave there the values he inserted? 2. When the user comes back to a page where he had a submitted POST data the browser keeps telling that the data has expired and asks if repost. How to avoid that? I tried registering all POST and GET vars as SESSION vars but
1
6890
by: inderjit S Gabrie | last post by:
Hi all Here is the scenerio ...is it possibly to do this... i am getting valid course dates output on to a web which i have designed ....all is okay so far , look at the following web url http://www.mis.gla.ac.uk/biquery/training/ but each of the courses held have maximum of 8 people that could be
2
31461
by: Jack | last post by:
Hi All, What is the PHP equivilent of Oracle bind variables in a SQL statement, e.g. select x from y where z=:parameter Which in asp/jsp would be followed by some statements to bind a value to :parameter I dont like the idea of making the SQL statement on the fly without binding parameters as I dont want a highly polluted SQL cache.
3
23617
by: Sandwick | last post by:
I am trying to change the size of a drawing so they are all 3x3. the script below is what i was trying to use to cut it in half ... I get errors. I can display the normal picture but not the results of the picture half the size. The PHP I have installed support 1.62 or higher. And all I would like to do is take and image and make it fit a 3x3. Any suggestions to where I should read or look would be appreciated.
0
9791
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,...
0
11137
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, 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...
0
10742
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 tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
10410
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 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...
0
9571
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, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
7122
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
1
4609
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
2
4215
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
3231
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 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...

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.